ack-v3.5.0/0000755000175100017510000000000014023040526011111 5ustar andyandyack-v3.5.0/t/0000755000175100017510000000000014023040526011354 5ustar andyandyack-v3.5.0/t/swamp/0000755000175100017510000000000014023040526012503 5ustar andyandyack-v3.5.0/t/swamp/moose-andy.jpg0000644000175100017510000001720513770736066015310 0ustar andyandyJFIFHHHICC_PROFILE8appl mntrRGB XYZ  acspAPPLappl-appl cprtHdesc1wtptHrTRC\gTRC\bTRC\rXYZlgXYZbXYZvcgt0chad,dscmLdesc sRGB Profile sRGB ProfileXYZ Qcurv3XYZ o8XYZ bXYZ $vcgtHHHsf32 B&ntextCopyright 1998 - 2003 Apple Computer Inc., all rights reserved.mluc enUSesES2daDK pdeDEHfiFIfrFUitITnlNLnoNOptBR2svSEjaJP koKRzhTW zhCN^sRGB-profiilisRGB-profilProfil sRVBsRGB 000000sRGB r_icϏPerfil sRGBsRGB-ProfilsRGB cϏeNsRGB-beskrivelsesRGB-profielsRGB \ |Profilo sRGBsRGB ProfileC   CNd  :!1"AQa #2BRq3 b5 !1AQaq"#2BRb ?ir>s5QM.\Js!o>,]TĞ-7LNiEԚR~zWCR@L6gy%0(ۛXHn|ԃN&f.G}<[b cG$֕Tovo[͕ßS#qs||‚7|*'ZN)W꺗xEƕh!IUTD$ORz?jUTԦ'aNdtz]Dk%o\_̆B ʈh.-1ㇸR74aمytusƠh-RRbH=aŰJErFQbH$42qhZ~*IΨI41 wyӆDdGM|c["0#J*'b Q#sid%""8i/^.vZ5Z#Pa+tj`mԎ[pO3Ƨ0),hVhrNTv"Us'l R?n>FB{ 3&]jƵ9Eس8DT~2xyXC!rtƵF6}ןٴ=F5&O+?$#>Sseeⴶ*`[EM~;eBJ X&Fr9Qv'T(1_j? F7NʂҤ|H ~pt"8z!GΛ-w]6䋮Kr S}-yd.(r[ ֝m&N=VmClENzJqhOkCJi yKӜZSqqn9hxRu]T¼ Tv#s v3ן!PS`HiVB|(c ܬ~XDgM_1Rbl-@HFEýEĸP!~fwK@V}h%{[ƇD6@V=}˴XmrB؅ǧ0ҥFmWsgm\\h,IrJTl>syhlsCʽ-îWڭó3Je(P-nh&u[󊚏uGrZ632VvWٶYU+dB'sNKFt"ͼ|fq5sJU e.A H8mZj7h(}&kiGyk%GCsNTH^0ԍU$Ƈ,RNVgN>դ;q ϶P029{rNA2ÃCc8fRo[G5RJҩSYq+U)+-A9Fr2ьj|>`x47qgv5Uȵzt¥2D8Y҆ךq * \q|89]"S':U>Ѻdݵ}cU(LdBBi}P^TAٷ ) wKo=8C4PWnpzcUimG>ULHR7y%#Hx:eN׍*W1x$6<:}^Z}M6fe.T: 76+L!@K sٌ9f\Jixhp:>1b į~LM7F1|A_[uӦFr?vR+r;<9g:&0SE!CPl)Dt5[dRo8dJe rsEU(4H0٤ԛԨaQ?Ϋ[Ns}d:紩Ԝq3!Ki;+}:T3( u̡\ &$;]r}lbIsJq:A_- ifњ4sVitR8Dp)攝;+s*i*#c>%Qi$;A>X)kBiʘMP>!”%ӌ,*"eҮ;Bu4IɢD !)zlŽ ^zo {M,D۽6t;t r6 PIA3A1/Wk a岘kܤO}uzM6j7_y:Tj7l@cOnj D5N%YnLM"ޠzC5ֿTNu*BL%)R%)g C 0G|㝼h |rտ|XYs5I+yi-U"2 9 ;M+UZq%ҝ۪2gIJab N1aRTB?IT-rTǍyEeƚCT;ޛwS-(n$L\Tf;-M4(O%K%(p0q-;Z(/7Η{7dxl{Z_\'*u!;B yơðv]*)sYǘ׋/uIN{g ʗl?(ʗH6wRqu[KI~[uIO(zBy'=LN[z~a("۞ˬR"LڂSͣ~=P l/!`y% SjY~ZTrTIұDLM<%*9|^C=ziytpMԛΣLd¼a9T2P?6wu3(!*m5JED3a[E뱘J'ki O?Γ`[Ljԧ20ryNb[B;ct6ELkn'UʑPS6-(@((޲ou j:4KrhԢ"3i8#R8H*<t>ƸɑLTd!,r cs)n`ɥBpQܬUpj/&0S 8V0$$0▱$R,%z[Q)!4-PˊH!@d}.̡TRl1.KK(TW[rB4.X=:AS*& C2r*r=GNۜ9L6>Q*:oTH:6ĭiX]jVkF\d%HDɐ[*HC$ 9Ul'VV4/^qAtzIAZ (>B[W)c[(A<'ץDsk'a^1LbwVTp^EB  h艺4,8['s''ߏlii)T[BØHƥ1K=\c0͹)>$K?P[N}K'|wr}N{kֲJCc@Q=xGq' ee tӨ!6fT.CacG<uƟZEBcг2kA5CeS>ϥ11-- AI8*g]ޢ>'l*Yxꤔ)a! qJNq{m4VnuLSwO>-e$Ўxi*Mеܱc4`O;ԛZA ([5%';JM&9-(h^1*N͔!eʜ OU%JO:MR̙NKkR[PYQmPέʺ BRm oު70F>PZzd+f ^Je*”yGr8*:B~=S"mTu}|,,8JHG5HaխɅTZs5<0(6KB!i[L[R[n$@2%,U<+76 GrH.C~:YQ硒 X% *o_XrOM9Mq۩#<|g{+xZ#x> QKT62y ?5SҫK2GH{G}:NMbQ.(-DRZOS8=\ZK2M:IA I=0UC֧~^/;K[jd<5d ˍ`DԢAO\UR }eJ/ 8.kR7Tu0RBe= r/}ZU҈U˯~|2nq5ONc(UE>%lr' - JϬ&uR{ǨiLp  Rg DDSC ]iFIbs*qK8ZNrUQ8C'ڐ?ER)OU=VY!=dNk#IW;}֥)yiAXg!T" pխf#RjH; Fw ~Qo -TUn#3z-D[uTSP4gZ&!8!T4GG.6fր~>XU qh3dFDd!^a9ޢI4ܢRs " )FGack-v3.5.0/t/swamp/groceries/0000755000175100017510000000000014023040526014465 5ustar andyandyack-v3.5.0/t/swamp/groceries/junk0000644000175100017510000000005214023027176015362 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/another_subdir/0000755000175100017510000000000014023040526017475 5ustar andyandyack-v3.5.0/t/swamp/groceries/another_subdir/CVS/0000755000175100017510000000000014023040526020130 5ustar andyandyack-v3.5.0/t/swamp/groceries/another_subdir/CVS/meat0000644000175100017510000000002213770736066021016 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/another_subdir/CVS/fruit0000644000175100017510000000002213770736066021221 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/another_subdir/CVS/junk0000644000175100017510000000005213770736066021042 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/another_subdir/RCS/0000755000175100017510000000000014023040526020124 5ustar andyandyack-v3.5.0/t/swamp/groceries/another_subdir/RCS/junk0000644000175100017510000000005213770736066021036 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/another_subdir/RCS/meat0000644000175100017510000000002213770736066021012 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/another_subdir/RCS/fruit0000644000175100017510000000002213770736066021215 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/another_subdir/fruit0000644000175100017510000000002214023027176020551 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/another_subdir/meat0000644000175100017510000000002214023027176020346 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/another_subdir/junk0000644000175100017510000000005214023027176020372 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/dir.d/0000755000175100017510000000000014023040526015465 5ustar andyandyack-v3.5.0/t/swamp/groceries/dir.d/RCS/0000755000175100017510000000000014023040526016114 5ustar andyandyack-v3.5.0/t/swamp/groceries/dir.d/RCS/meat0000644000175100017510000000002213770736066017002 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/dir.d/RCS/junk0000644000175100017510000000005213770736066017026 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/dir.d/RCS/fruit0000644000175100017510000000002213770736066017205 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/dir.d/CVS/0000755000175100017510000000000014023040526016120 5ustar andyandyack-v3.5.0/t/swamp/groceries/dir.d/CVS/junk0000644000175100017510000000005213770736066017032 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/dir.d/CVS/fruit0000644000175100017510000000002213770736066017211 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/dir.d/CVS/meat0000644000175100017510000000002213770736066017006 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/dir.d/fruit0000644000175100017510000000002214023027176016541 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/dir.d/meat0000644000175100017510000000002214023027176016336 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/dir.d/junk0000644000175100017510000000005214023027176016362 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/subdir/0000755000175100017510000000000014023040526015755 5ustar andyandyack-v3.5.0/t/swamp/groceries/subdir/meat0000644000175100017510000000002214023027176016626 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/subdir/junk0000644000175100017510000000005214023027176016652 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/subdir/fruit0000644000175100017510000000002214023027176017031 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/RCS/0000755000175100017510000000000014023040526015114 5ustar andyandyack-v3.5.0/t/swamp/groceries/RCS/fruit0000644000175100017510000000002213770736066016205 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/RCS/junk0000644000175100017510000000005213770736066016026 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/RCS/meat0000644000175100017510000000002213770736066016002 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/meat0000644000175100017510000000002214023027176015336 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/groceries/fruit0000644000175100017510000000002214023027176015541 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/CVS/0000755000175100017510000000000014023040526015120 5ustar andyandyack-v3.5.0/t/swamp/groceries/CVS/junk0000644000175100017510000000005213770736066016032 0ustar andyandyapple fritters grape jam fried pork rinds ack-v3.5.0/t/swamp/groceries/CVS/fruit0000644000175100017510000000002213770736066016211 0ustar andyandyapple pear grapes ack-v3.5.0/t/swamp/groceries/CVS/meat0000644000175100017510000000002213770736066016006 0ustar andyandypork beef chicken ack-v3.5.0/t/swamp/__pycache__/0000755000175100017510000000000014023040526014713 5ustar andyandyack-v3.5.0/t/swamp/__pycache__/notes.pl0000644000175100017510000000026713770736066016430 0ustar andyandy#!/usr/bin/perl # This is a Perl file that should be ignored because it's in the __pycache__ directory. # # The Perl/Python doesn't matter, just that __pycache__ should be ignored. ack-v3.5.0/t/swamp/Rakefile0000644000175100017510000000420214023027176014154 0ustar andyandyrequire 'rubygems' require 'hoe' def announce(msg='') STDERR.puts msg end PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' PKG_NAME = 'mechanize' PKG_VERSION = '0.6.4' + PKG_BUILD Hoe.new(PKG_NAME, PKG_VERSION) do |p| p.rubyforge_name = PKG_NAME p.author = 'Aaron Patterson' p.email = 'aaronp@rubyforge.org' p.summary = "Mechanize provides automated web-browsing" p.description = p.paragraphs_of('README.txt', 3).join("\n\n") p.url = p.paragraphs_of('README.txt', 1).first.strip p.changes = p.paragraphs_of('CHANGELOG.txt', 0..2).join("\n\n") files = (p.test_globs + ['test/**/tc_*.rb', "test/htdocs/**/*.{html,jpg}", 'test/data/server.*']).map { |x| Dir.glob(x) }.flatten + ['test/data/htpasswd'] p.extra_deps = ['hpricot'] p.spec_extras = { :test_files => files } end task :update_version do announce "Updating Mechanize Version to #{PKG_VERSION}" File.open("lib/mechanize/mech_version.rb", "w") do |f| f.puts "module WWW" f.puts " class Mechanize" f.puts " Version = '#{PKG_VERSION}'" f.puts " end" f.puts "end" end sh 'svn commit -m"updating version" lib/mechanize/mech_version.rb' end desc "Tag code" Rake::Task.define_task("tag") do |p| baseurl = "svn+ssh://#{ENV['USER']}@rubyforge.org//var/svn/#{PKG_NAME}" sh "svn cp -m 'tagged #{ PKG_VERSION }' . #{ baseurl }/tags/REL-#{ PKG_VERSION }" end desc "Branch code" Rake::Task.define_task("branch") do |p| baseurl = "svn+ssh://#{ENV['USER']}@rubyforge.org/var/svn/#{PKG_NAME}" sh "svn cp -m 'branched #{ PKG_VERSION }' #{baseurl}/trunk #{ baseurl }/branches/RB-#{ PKG_VERSION }" end desc "Update SSL Certificate" Rake::Task.define_task('ssl_cert') do |p| sh "openssl genrsa -des3 -out server.key 1024" sh "openssl req -new -key server.key -out server.csr" sh "cp server.key server.key.org" sh "openssl rsa -in server.key.org -out server.key" sh "openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt" sh "cp server.key server.pem" sh "mv server.key server.csr server.crt server.pem test/data/" sh "rm server.key.org" end ack-v3.5.0/t/swamp/constitution-100k.pl0000644000175100017510000031145714023027176016274 0ustar andyandy=head1 This file exists just to have slightly over 100K of content, and then have a some text to find at the end. It is to test the needs_line_scan() function. Unfortunately, we've updated the size that we read for buffering is 10MB, so this doesn't really test it. # Preamble We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America. # Article I ## Section 1 All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives. ## Section 2 The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment. ## Section 3 The Senate of the United States shall be composed of two Senators from each State, chosen by the Legislature thereof, for six Years; and each Senator shall have one Vote. Immediately after they shall be assembled in Consequence of the first Election, they shall be divided as equally as may be into three Classes. The Seats of the Senators of the first Class shall be vacated at the Expiration of the second Year, of the second Class at the Expiration of the fourth Year, and of the third Class at the Expiration of the sixth Year, so that one third may be chosen every second Year; and if Vacancies happen by Resignation, or otherwise, during the Recess of the Legislature of any State, the Executive thereof may make temporary Appointments until the next Meeting of the Legislature, which shall then fill such Vacancies. No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen. The Vice President of the United States shall be President of the Senate, but shall have no Vote, unless they be equally divided. The Senate shall chuse their other Officers, and also a President pro tempore, in the Absence of the Vice President, or when he shall exercise the Office of President of the United States. The Senate shall have the sole Power to try all Impeachments. When sitting for that Purpose, they shall be on Oath or Affirmation. When the President of the United States is tried, the Chief Justice shall preside: And no Person shall be convicted without the Concurrence of two thirds of the Members present. Judgment in Cases of Impeachment shall not extend further than to removal from Office, and disqualification to hold and enjoy any Office of honor, Trust or Profit under the United States: but the Party convicted shall nevertheless be liable and subject to Indictment, Trial, Judgment and Punishment, according to Law. ## Section 4 The Times, Places and Manner of holding Elections for Senators and Representatives, shall be prescribed in each State by the Legislature thereof; but the Congress may at any time by Law make or alter such Regulations, except as to the Places of chusing Senators. The Congress shall assemble at least once in every Year, and such Meeting shall be on the first Monday in December, unless they shall by Law appoint a different Day. ## Section 5 Each House shall be the Judge of the Elections, Returns and Qualifications of its own Members, and a Majority of each shall constitute a Quorum to do Business; but a smaller Number may adjourn from day to day, and may be authorized to compel the Attendance of absent Members, in such Manner, and under such Penalties as each House may provide. Each House may determine the Rules of its Proceedings, punish its Members for disorderly Behaviour, and, with the Concurrence of two thirds, expel a Member. Each House shall keep a Journal of its Proceedings, and from time to time publish the same, excepting such Parts as may in their Judgment require Secrecy; and the Yeas and Nays of the Members of either House on any question shall, at the Desire of one fifth of those Present, be entered on the Journal. Neither House, during the Session of Congress, shall, without the Consent of the other, adjourn for more than three days, nor to any other Place than that in which the two Houses shall be sitting. ## Section 6 The Senators and Representatives shall receive a Compensation for their Services, to be ascertained by Law, and paid out of the Treasury of the United States. They shall in all Cases, except Treason, Felony and Breach of the Peace, be privileged from Arrest during their Attendance at the Session of their respective Houses, and in going to and returning from the same; and for any Speech or Debate in either House, they shall not be questioned in any other Place. No Senator or Representative shall, during the Time for which he was elected, be appointed to any civil Office under the Authority of the United States, which shall have been created, or the Emoluments whereof shall have been encreased during such time; and no Person holding any Office under the United States, shall be a Member of either House during his Continuance in Office. ## Section 7 All Bills for raising Revenue shall originate in the House of Representatives; but the Senate may propose or concur with Amendments as on other Bills. Every Bill which shall have passed the House of Representatives and the Senate, shall, before it become a Law, be presented to the President of the United States: If he approve he shall sign it, but if not he shall return it, with his Objections to that House in which it shall have originated, who shall enter the Objections at large on their Journal, and proceed to reconsider it. If after such Reconsideration two thirds of that House shall agree to pass the Bill, it shall be sent, together with the Objections, to the other House, by which it shall likewise be reconsidered, and if approved by two thirds of that House, it shall become a Law. But in all such Cases the Votes of both Houses shall be determined by Yeas and Nays, and the Names of the Persons voting for and against the Bill shall be entered on the Journal of each House respectively. If any Bill shall not be returned by the President within ten Days (Sundays excepted) after it shall have been presented to him, the Same shall be a Law, in like Manner as if he had signed it, unless the Congress by their Adjournment prevent its Return, in which Case it shall not be a Law. Every Order, Resolution, or Vote to which the Concurrence of the Senate and House of Representatives may be necessary (except on a question of Adjournment) shall be presented to the President of the United States; and before the Same shall take Effect, shall be approved by him, or being disapproved by him, shall be repassed by two thirds of the Senate and House of Representatives, according to the Rules and Limitations prescribed in the Case of a Bill. ## Section 8 The Congress shall have Power To lay and collect Taxes, Duties, Imposts and Excises, to pay the Debts and provide for the common Defence and general Welfare of the United States; but all Duties, Imposts and Excises shall be uniform throughout the United States; To borrow Money on the credit of the United States; To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes; To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States; To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures; To provide for the Punishment of counterfeiting the Securities and current Coin of the United States; To establish Post Offices and post Roads; To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries; To constitute Tribunals inferior to the supreme Court; To define and punish Piracies and Felonies committed on the high Seas, and Offences against the Law of Nations; To declare War, grant Letters of Marque and Reprisal, and make Rules concerning Captures on Land and Water; To raise and support Armies, but no Appropriation of Money to that Use shall be for a longer Term than two Years; To provide and maintain a Navy; To make Rules for the Government and Regulation of the land and naval Forces; To provide for calling forth the Militia to execute the Laws of the Union, suppress Insurrections and repel Invasions; To provide for organizing, arming, and disciplining, the Militia, and for governing such Part of them as may be employed in the Service of the United States, reserving to the States respectively, the Appointment of the Officers, and the Authority of training the Militia according to the discipline prescribed by Congress; To exercise exclusive Legislation in all Cases whatsoever, over such District (not exceeding ten Miles square) as may, by Cession of particular States, and the Acceptance of Congress, become the Seat of the Government of the United States, and to exercise like Authority over all Places purchased by the Consent of the Legislature of the State in which the Same shall be, for the Erection of Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings;-And To make all Laws which shall be necessary and proper for carrying into Execution the foregoing Powers, and all other Powers vested by this Constitution in the Government of the United States, or in any Department or Officer thereof. ## Section 9 The Migration or Importation of such Persons as any of the States now existing shall think proper to admit, shall not be prohibited by the Congress prior to the Year one thousand eight hundred and eight, but a Tax or duty may be imposed on such Importation, not exceeding ten dollars for each Person. The Privilege of the Writ of Habeas Corpus shall not be suspended, unless when in Cases of Rebellion or Invasion the public Safety may require it. No Bill of Attainder or ex post facto Law shall be passed. No Capitation, or other direct, Tax shall be laid, unless in Proportion to the Census or enumeration herein before directed to be taken. No Tax or Duty shall be laid on Articles exported from any State. No Preference shall be given by any Regulation of Commerce or Revenue to the Ports of one State over those of another; nor shall Vessels bound to, or from, one State, be obliged to enter, clear, or pay Duties in another. No Money shall be drawn from the Treasury, but in Consequence of Appropriations made by Law; and a regular Statement and Account of the Receipts and Expenditures of all public Money shall be published from time to time. No Title of Nobility shall be granted by the United States: And no Person holding any Office of Profit or Trust under them, shall, without the Consent of the Congress, accept of any present, Emolument, Office, or Title, of any kind whatever, from any King, Prince, or foreign State. ## Section 10 No State shall enter into any Treaty, Alliance, or Confederation; grant Letters of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder, ex post facto Law, or Law impairing the Obligation of Contracts, or grant any Title of Nobility. No State shall, without the Consent of the Congress, lay any Imposts or Duties on Imports or Exports, except what may be absolutely necessary for executing its inspection Laws: and the net Produce of all Duties and Imposts, laid by any State on Imports or Exports, shall be for the Use of the Treasury of the United States; and all such Laws shall be subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, keep Troops, or Ships of War in time of Peace, enter into any Agreement or Compact with another State, or with a foreign Power, or engage in War, unless actually invaded, or in such imminent Danger as will not admit of delay. # Article II ## Section 1 The executive Power shall be vested in a President of the United States of America. He shall hold his Office during the Term of four Years, and, together with the Vice President, chosen for the same Term, be elected, as follows: Each State shall appoint, in such Manner as the Legislature thereof may direct, a Number of Electors, equal to the whole Number of Senators and Representatives to which the State may be entitled in the Congress: but no Senator or Representative, or Person holding an Office of Trust or Profit under the United States, shall be appointed an Elector. The Electors shall meet in their respective States, and vote by Ballot for two Persons, of whom one at least shall not be an Inhabitant of the same State with themselves. And they shall make a List of all the Persons voted for, and of the Number of Votes for each; which List they shall sign and certify, and transmit sealed to the Seat of the Government of the United States, directed to the President of the Senate. The President of the Senate shall, in the Presence of the Senate and House of Representatives, open all the Certificates, and the Votes shall then be counted. The Person having the greatest Number of Votes shall be the President, if such Number be a Majority of the whole Number of Electors appointed; and if there be more than one who have such Majority, and have an equal Number of Votes, then the House of Representatives shall immediately chuse by Ballot one of them for President; and if no Person have a Majority, then from the five highest on the List the said House shall in like Manner chuse the President. But in chusing the President, the Votes shall be taken by States, the Representatives from each State having one Vote; a quorum for this Purpose shall consist of a Member or Members from two thirds of the States, and a Majority of all the States shall be necessary to a Choice. In every Case, after the Choice of the President, the Person having the greatest Number of Votes of the Electors shall be the Vice President. But if there should remain two or more who have equal Votes, the Senate shall chuse from them by Ballot the Vice-President. The Congress may determine the Time of chusing the Electors, and the Day on which they shall give their Votes; which Day shall be the same throughout the United States. No Person except a natural born Citizen, or a Citizen of the United States, at the time of the Adoption of this Constitution, shall be eligible to the Office of President; neither shall any person be eligible to that Office who shall not have attained to the Age of thirty five Years, and been fourteen Years a Resident within the United States. In Case of the Removal of the President from Office, or of his Death, Resignation, or Inability to discharge the Powers and Duties of the said Office, the Same shall devolve on the Vice President, and the Congress may by Law provide for the Case of Removal, Death, Resignation or Inability, both of the President and Vice President, declaring what Officer shall then act as President, and such Officer shall act accordingly, until the Disability be removed, or a President shall be elected. The President shall, at stated Times, receive for his Services, a Compensation, which shall neither be encreased nor diminished during the Period for which he shall have been elected, and he shall not receive within that Period any other Emolument from the United States, or any of them. Before he enter on the Execution of his Office, he shall take the following Oath or Affirmation:-"I do solemnly swear (or affirm) that I will faithfully execute the Office of President of the United States, and will to the best of my Ability, preserve, protect and defend the Constitution of the United States." ## Section 2 The President shall be Commander in Chief of the Army and Navy of the United States, and of the Militia of the several States, when called into the actual Service of the United States; he may require the Opinion, in writing, of the principal Officer in each of the executive Departments, upon any Subject relating to the Duties of their respective Offices, and he shall have Power to Grant Reprieves and Pardons for Offences against the United States, except in Cases of Impeachment. He shall have Power, by and with the Advice and Consent of the Senate, to make Treaties, provided two thirds of the Senators present concur; and he shall nominate, and by and with the Advice and Consent of the Senate, shall appoint Ambassadors, other public Ministers and Consuls, Judges of the supreme Court, and all other Officers of the United States, whose Appointments are not herein otherwise provided for, and which shall be established by Law: but the Congress may by Law vest the Appointment of such inferior Officers, as they think proper, in the President alone, in the Courts of Law, or in the Heads of Departments. The President shall have Power to fill up all Vacancies that may happen during the Recess of the Senate, by granting Commissions which shall expire at the End of their next Session. ## Section 3 He shall from time to time give to the Congress Information on the State of the Union, and recommend to their Consideration such Measures as he shall judge necessary and expedient; he may, on extraordinary Occasions, convene both Houses, or either of them, and in Case of Disagreement between them, with Respect to the Time of Adjournment, he may adjourn them to such Time as he shall think proper; he shall receive Ambassadors and other public Ministers; he shall take Care that the Laws be faithfully executed, and shall Commission all the Officers of the United States. ## Section 4 The President, Vice President and all Civil Officers of the United States, shall be removed from Office on Impeachment for, and Conviction of, Treason, Bribery, or other high Crimes and Misdemeanors. # Article III ## Section 1 The judicial Power of the United States, shall be vested in one supreme Court, and in such inferior Courts as the Congress may from time to time ordain and establish. The Judges, both of the supreme and inferior Courts, shall hold their Offices during good Behaviour, and shall, at stated Times, receive for their Services, a Compensation, which shall not be diminished during their Continuance in Office. ## Section 2 The judicial Power shall extend to all Cases, in Law and Equity, arising under this Constitution, the Laws of the United States, and Treaties made, or which shall be made, under their Authority; -- to all Cases affecting Ambassadors, other public ministers and Consuls; -- to all Cases of admiralty and maritime Jurisdiction; -- to Controversies to which the United States shall be a Party; -- to Controversies between two or more States; -- between a State and Citizens of another State; -- between Citizens of different States; -- between Citizens of the same State claiming Lands under Grants of different States, and between a State, or the Citizens thereof, and foreign States, Citizens or Subjects. In all Cases affecting Ambassadors, other public Ministers and Consuls, and those in which a State shall be Party, the supreme Court shall have original Jurisdiction. In all the other Cases before mentioned, the supreme Court shall have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and under such Regulations as the Congress shall make. The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and such Trial shall be held in the State where the said Crimes shall have been committed; but when not committed within any State, the Trial shall be at such Place or Places as the Congress may by Law have directed. ## Section 3 Treason against the United States, shall consist only in levying War against them, or in adhering to their Enemies, giving them Aid and Comfort. No Person shall be convicted of Treason unless on the Testimony of two Witnesses to the same overt Act, or on Confession in open Court. The Congress shall have Power to declare the Punishment of Treason, but no Attainder of Treason shall work Corruption of Blood, or Forfeiture except during the Life of the Person attainted. # Article IV ## Section 1 Full Faith and Credit shall be given in each State to the public Acts, Records, and judicial Proceedings of every other State. And the Congress may by general Laws prescribe the Manner in which such Acts, Records and Proceedings shall be proved, and the Effect thereof. ## Section 2 The Citizens of each State shall be entitled to all Privileges and Immunities of Citizens in the several States. A Person charged in any State with Treason, Felony, or other Crime, who shall flee from Justice, and be found in another State, shall on Demand of the executive Authority of the State from which he fled, be delivered up, to be removed to the State having Jurisdiction of the Crime. No Person held to Service or Labour in one State, under the Laws thereof, escaping into another, shall, in Consequence of any Law or Regulation therein, be discharged from such Service or Labour, but shall be delivered up on Claim of the Party to whom such Service or Labour may be due. ## Section 3 New States may be admitted by the Congress into this Union; but no new State shall be formed or erected within the Jurisdiction of any other State; nor any State be formed by the Junction of two or more States, or Parts of States, without the Consent of the Legislatures of the States concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and Regulations respecting the Territory or other Property belonging to the United States; and nothing in this Constitution shall be so construed as to Prejudice any Claims of the United States, or of any particular State. ## Section 4 The United States shall guarantee to every State in this Union a Republican Form of Government, and shall protect each of them against Invasion; and on Application of the Legislature, or of the Executive (when the Legislature cannot be convened) against domestic Violence. # Article V The Congress, whenever two thirds of both Houses shall deem it necessary, shall propose Amendments to this Constitution, or, on the Application of the Legislatures of two thirds of the several States, shall call a Convention for proposing Amendments, which, in either Case, shall be valid to all Intents and Purposes, as Part of this Constitution, when ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight shall in any Manner affect the first and fourth Clauses in the Ninth Section of the first Article; and that no State, without its Consent, shall be deprived of its equal Suffrage in the Senate. # Article VI All Debts contracted and Engagements entered into, before the Adoption of this Constitution, shall be as valid against the United States under this Constitution, as under the Confederation. This Constitution, and the Laws of the United States which shall be made in Pursuance thereof; and all Treaties made, or which shall be made, under the Authority of the United States, shall be the supreme Law of the Land; and the Judges in every State shall be bound thereby, any Thing in the Constitution or Laws of any state to the Contrary notwithstanding. The Senators and Representatives before mentioned, and the Members of the several State Legislatures, and all executive and judicial Officers, both of the United States and of the several States, shall be bound by Oath or Affirmation, to support this Constitution; but no religious Test shall ever be required as a Qualification to any Office or public Trust under the United States. # Article VII The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying the Same. # Preamble We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America. # Article I ## Section 1 All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives. ## Section 2 The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment. ## Section 3 The Senate of the United States shall be composed of two Senators from each State, chosen by the Legislature thereof, for six Years; and each Senator shall have one Vote. Immediately after they shall be assembled in Consequence of the first Election, they shall be divided as equally as may be into three Classes. The Seats of the Senators of the first Class shall be vacated at the Expiration of the second Year, of the second Class at the Expiration of the fourth Year, and of the third Class at the Expiration of the sixth Year, so that one third may be chosen every second Year; and if Vacancies happen by Resignation, or otherwise, during the Recess of the Legislature of any State, the Executive thereof may make temporary Appointments until the next Meeting of the Legislature, which shall then fill such Vacancies. No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen. The Vice President of the United States shall be President of the Senate, but shall have no Vote, unless they be equally divided. The Senate shall chuse their other Officers, and also a President pro tempore, in the Absence of the Vice President, or when he shall exercise the Office of President of the United States. The Senate shall have the sole Power to try all Impeachments. When sitting for that Purpose, they shall be on Oath or Affirmation. When the President of the United States is tried, the Chief Justice shall preside: And no Person shall be convicted without the Concurrence of two thirds of the Members present. Judgment in Cases of Impeachment shall not extend further than to removal from Office, and disqualification to hold and enjoy any Office of honor, Trust or Profit under the United States: but the Party convicted shall nevertheless be liable and subject to Indictment, Trial, Judgment and Punishment, according to Law. ## Section 4 The Times, Places and Manner of holding Elections for Senators and Representatives, shall be prescribed in each State by the Legislature thereof; but the Congress may at any time by Law make or alter such Regulations, except as to the Places of chusing Senators. The Congress shall assemble at least once in every Year, and such Meeting shall be on the first Monday in December, unless they shall by Law appoint a different Day. ## Section 5 Each House shall be the Judge of the Elections, Returns and Qualifications of its own Members, and a Majority of each shall constitute a Quorum to do Business; but a smaller Number may adjourn from day to day, and may be authorized to compel the Attendance of absent Members, in such Manner, and under such Penalties as each House may provide. Each House may determine the Rules of its Proceedings, punish its Members for disorderly Behaviour, and, with the Concurrence of two thirds, expel a Member. Each House shall keep a Journal of its Proceedings, and from time to time publish the same, excepting such Parts as may in their Judgment require Secrecy; and the Yeas and Nays of the Members of either House on any question shall, at the Desire of one fifth of those Present, be entered on the Journal. Neither House, during the Session of Congress, shall, without the Consent of the other, adjourn for more than three days, nor to any other Place than that in which the two Houses shall be sitting. ## Section 6 The Senators and Representatives shall receive a Compensation for their Services, to be ascertained by Law, and paid out of the Treasury of the United States. They shall in all Cases, except Treason, Felony and Breach of the Peace, be privileged from Arrest during their Attendance at the Session of their respective Houses, and in going to and returning from the same; and for any Speech or Debate in either House, they shall not be questioned in any other Place. No Senator or Representative shall, during the Time for which he was elected, be appointed to any civil Office under the Authority of the United States, which shall have been created, or the Emoluments whereof shall have been encreased during such time; and no Person holding any Office under the United States, shall be a Member of either House during his Continuance in Office. ## Section 7 All Bills for raising Revenue shall originate in the House of Representatives; but the Senate may propose or concur with Amendments as on other Bills. Every Bill which shall have passed the House of Representatives and the Senate, shall, before it become a Law, be presented to the President of the United States: If he approve he shall sign it, but if not he shall return it, with his Objections to that House in which it shall have originated, who shall enter the Objections at large on their Journal, and proceed to reconsider it. If after such Reconsideration two thirds of that House shall agree to pass the Bill, it shall be sent, together with the Objections, to the other House, by which it shall likewise be reconsidered, and if approved by two thirds of that House, it shall become a Law. But in all such Cases the Votes of both Houses shall be determined by Yeas and Nays, and the Names of the Persons voting for and against the Bill shall be entered on the Journal of each House respectively. If any Bill shall not be returned by the President within ten Days (Sundays excepted) after it shall have been presented to him, the Same shall be a Law, in like Manner as if he had signed it, unless the Congress by their Adjournment prevent its Return, in which Case it shall not be a Law. Every Order, Resolution, or Vote to which the Concurrence of the Senate and House of Representatives may be necessary (except on a question of Adjournment) shall be presented to the President of the United States; and before the Same shall take Effect, shall be approved by him, or being disapproved by him, shall be repassed by two thirds of the Senate and House of Representatives, according to the Rules and Limitations prescribed in the Case of a Bill. ## Section 8 The Congress shall have Power To lay and collect Taxes, Duties, Imposts and Excises, to pay the Debts and provide for the common Defence and general Welfare of the United States; but all Duties, Imposts and Excises shall be uniform throughout the United States; To borrow Money on the credit of the United States; To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes; To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States; To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures; To provide for the Punishment of counterfeiting the Securities and current Coin of the United States; To establish Post Offices and post Roads; To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries; To constitute Tribunals inferior to the supreme Court; To define and punish Piracies and Felonies committed on the high Seas, and Offences against the Law of Nations; To declare War, grant Letters of Marque and Reprisal, and make Rules concerning Captures on Land and Water; To raise and support Armies, but no Appropriation of Money to that Use shall be for a longer Term than two Years; To provide and maintain a Navy; To make Rules for the Government and Regulation of the land and naval Forces; To provide for calling forth the Militia to execute the Laws of the Union, suppress Insurrections and repel Invasions; To provide for organizing, arming, and disciplining, the Militia, and for governing such Part of them as may be employed in the Service of the United States, reserving to the States respectively, the Appointment of the Officers, and the Authority of training the Militia according to the discipline prescribed by Congress; To exercise exclusive Legislation in all Cases whatsoever, over such District (not exceeding ten Miles square) as may, by Cession of particular States, and the Acceptance of Congress, become the Seat of the Government of the United States, and to exercise like Authority over all Places purchased by the Consent of the Legislature of the State in which the Same shall be, for the Erection of Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings;-And To make all Laws which shall be necessary and proper for carrying into Execution the foregoing Powers, and all other Powers vested by this Constitution in the Government of the United States, or in any Department or Officer thereof. ## Section 9 The Migration or Importation of such Persons as any of the States now existing shall think proper to admit, shall not be prohibited by the Congress prior to the Year one thousand eight hundred and eight, but a Tax or duty may be imposed on such Importation, not exceeding ten dollars for each Person. The Privilege of the Writ of Habeas Corpus shall not be suspended, unless when in Cases of Rebellion or Invasion the public Safety may require it. No Bill of Attainder or ex post facto Law shall be passed. No Capitation, or other direct, Tax shall be laid, unless in Proportion to the Census or enumeration herein before directed to be taken. No Tax or Duty shall be laid on Articles exported from any State. No Preference shall be given by any Regulation of Commerce or Revenue to the Ports of one State over those of another; nor shall Vessels bound to, or from, one State, be obliged to enter, clear, or pay Duties in another. No Money shall be drawn from the Treasury, but in Consequence of Appropriations made by Law; and a regular Statement and Account of the Receipts and Expenditures of all public Money shall be published from time to time. No Title of Nobility shall be granted by the United States: And no Person holding any Office of Profit or Trust under them, shall, without the Consent of the Congress, accept of any present, Emolument, Office, or Title, of any kind whatever, from any King, Prince, or foreign State. ## Section 10 No State shall enter into any Treaty, Alliance, or Confederation; grant Letters of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder, ex post facto Law, or Law impairing the Obligation of Contracts, or grant any Title of Nobility. No State shall, without the Consent of the Congress, lay any Imposts or Duties on Imports or Exports, except what may be absolutely necessary for executing its inspection Laws: and the net Produce of all Duties and Imposts, laid by any State on Imports or Exports, shall be for the Use of the Treasury of the United States; and all such Laws shall be subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, keep Troops, or Ships of War in time of Peace, enter into any Agreement or Compact with another State, or with a foreign Power, or engage in War, unless actually invaded, or in such imminent Danger as will not admit of delay. # Article II ## Section 1 The executive Power shall be vested in a President of the United States of America. He shall hold his Office during the Term of four Years, and, together with the Vice President, chosen for the same Term, be elected, as follows: Each State shall appoint, in such Manner as the Legislature thereof may direct, a Number of Electors, equal to the whole Number of Senators and Representatives to which the State may be entitled in the Congress: but no Senator or Representative, or Person holding an Office of Trust or Profit under the United States, shall be appointed an Elector. The Electors shall meet in their respective States, and vote by Ballot for two Persons, of whom one at least shall not be an Inhabitant of the same State with themselves. And they shall make a List of all the Persons voted for, and of the Number of Votes for each; which List they shall sign and certify, and transmit sealed to the Seat of the Government of the United States, directed to the President of the Senate. The President of the Senate shall, in the Presence of the Senate and House of Representatives, open all the Certificates, and the Votes shall then be counted. The Person having the greatest Number of Votes shall be the President, if such Number be a Majority of the whole Number of Electors appointed; and if there be more than one who have such Majority, and have an equal Number of Votes, then the House of Representatives shall immediately chuse by Ballot one of them for President; and if no Person have a Majority, then from the five highest on the List the said House shall in like Manner chuse the President. But in chusing the President, the Votes shall be taken by States, the Representatives from each State having one Vote; a quorum for this Purpose shall consist of a Member or Members from two thirds of the States, and a Majority of all the States shall be necessary to a Choice. In every Case, after the Choice of the President, the Person having the greatest Number of Votes of the Electors shall be the Vice President. But if there should remain two or more who have equal Votes, the Senate shall chuse from them by Ballot the Vice-President. The Congress may determine the Time of chusing the Electors, and the Day on which they shall give their Votes; which Day shall be the same throughout the United States. No Person except a natural born Citizen, or a Citizen of the United States, at the time of the Adoption of this Constitution, shall be eligible to the Office of President; neither shall any person be eligible to that Office who shall not have attained to the Age of thirty five Years, and been fourteen Years a Resident within the United States. In Case of the Removal of the President from Office, or of his Death, Resignation, or Inability to discharge the Powers and Duties of the said Office, the Same shall devolve on the Vice President, and the Congress may by Law provide for the Case of Removal, Death, Resignation or Inability, both of the President and Vice President, declaring what Officer shall then act as President, and such Officer shall act accordingly, until the Disability be removed, or a President shall be elected. The President shall, at stated Times, receive for his Services, a Compensation, which shall neither be encreased nor diminished during the Period for which he shall have been elected, and he shall not receive within that Period any other Emolument from the United States, or any of them. Before he enter on the Execution of his Office, he shall take the following Oath or Affirmation:-"I do solemnly swear (or affirm) that I will faithfully execute the Office of President of the United States, and will to the best of my Ability, preserve, protect and defend the Constitution of the United States." ## Section 2 The President shall be Commander in Chief of the Army and Navy of the United States, and of the Militia of the several States, when called into the actual Service of the United States; he may require the Opinion, in writing, of the principal Officer in each of the executive Departments, upon any Subject relating to the Duties of their respective Offices, and he shall have Power to Grant Reprieves and Pardons for Offences against the United States, except in Cases of Impeachment. He shall have Power, by and with the Advice and Consent of the Senate, to make Treaties, provided two thirds of the Senators present concur; and he shall nominate, and by and with the Advice and Consent of the Senate, shall appoint Ambassadors, other public Ministers and Consuls, Judges of the supreme Court, and all other Officers of the United States, whose Appointments are not herein otherwise provided for, and which shall be established by Law: but the Congress may by Law vest the Appointment of such inferior Officers, as they think proper, in the President alone, in the Courts of Law, or in the Heads of Departments. The President shall have Power to fill up all Vacancies that may happen during the Recess of the Senate, by granting Commissions which shall expire at the End of their next Session. ## Section 3 He shall from time to time give to the Congress Information on the State of the Union, and recommend to their Consideration such Measures as he shall judge necessary and expedient; he may, on extraordinary Occasions, convene both Houses, or either of them, and in Case of Disagreement between them, with Respect to the Time of Adjournment, he may adjourn them to such Time as he shall think proper; he shall receive Ambassadors and other public Ministers; he shall take Care that the Laws be faithfully executed, and shall Commission all the Officers of the United States. ## Section 4 The President, Vice President and all Civil Officers of the United States, shall be removed from Office on Impeachment for, and Conviction of, Treason, Bribery, or other high Crimes and Misdemeanors. # Article III ## Section 1 The judicial Power of the United States, shall be vested in one supreme Court, and in such inferior Courts as the Congress may from time to time ordain and establish. The Judges, both of the supreme and inferior Courts, shall hold their Offices during good Behaviour, and shall, at stated Times, receive for their Services, a Compensation, which shall not be diminished during their Continuance in Office. ## Section 2 The judicial Power shall extend to all Cases, in Law and Equity, arising under this Constitution, the Laws of the United States, and Treaties made, or which shall be made, under their Authority; -- to all Cases affecting Ambassadors, other public ministers and Consuls; -- to all Cases of admiralty and maritime Jurisdiction; -- to Controversies to which the United States shall be a Party; -- to Controversies between two or more States; -- between a State and Citizens of another State; -- between Citizens of different States; -- between Citizens of the same State claiming Lands under Grants of different States, and between a State, or the Citizens thereof, and foreign States, Citizens or Subjects. In all Cases affecting Ambassadors, other public Ministers and Consuls, and those in which a State shall be Party, the supreme Court shall have original Jurisdiction. In all the other Cases before mentioned, the supreme Court shall have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and under such Regulations as the Congress shall make. The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and such Trial shall be held in the State where the said Crimes shall have been committed; but when not committed within any State, the Trial shall be at such Place or Places as the Congress may by Law have directed. ## Section 3 Treason against the United States, shall consist only in levying War against them, or in adhering to their Enemies, giving them Aid and Comfort. No Person shall be convicted of Treason unless on the Testimony of two Witnesses to the same overt Act, or on Confession in open Court. The Congress shall have Power to declare the Punishment of Treason, but no Attainder of Treason shall work Corruption of Blood, or Forfeiture except during the Life of the Person attainted. # Article IV ## Section 1 Full Faith and Credit shall be given in each State to the public Acts, Records, and judicial Proceedings of every other State. And the Congress may by general Laws prescribe the Manner in which such Acts, Records and Proceedings shall be proved, and the Effect thereof. ## Section 2 The Citizens of each State shall be entitled to all Privileges and Immunities of Citizens in the several States. A Person charged in any State with Treason, Felony, or other Crime, who shall flee from Justice, and be found in another State, shall on Demand of the executive Authority of the State from which he fled, be delivered up, to be removed to the State having Jurisdiction of the Crime. No Person held to Service or Labour in one State, under the Laws thereof, escaping into another, shall, in Consequence of any Law or Regulation therein, be discharged from such Service or Labour, but shall be delivered up on Claim of the Party to whom such Service or Labour may be due. ## Section 3 New States may be admitted by the Congress into this Union; but no new State shall be formed or erected within the Jurisdiction of any other State; nor any State be formed by the Junction of two or more States, or Parts of States, without the Consent of the Legislatures of the States concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and Regulations respecting the Territory or other Property belonging to the United States; and nothing in this Constitution shall be so construed as to Prejudice any Claims of the United States, or of any particular State. ## Section 4 The United States shall guarantee to every State in this Union a Republican Form of Government, and shall protect each of them against Invasion; and on Application of the Legislature, or of the Executive (when the Legislature cannot be convened) against domestic Violence. # Article V The Congress, whenever two thirds of both Houses shall deem it necessary, shall propose Amendments to this Constitution, or, on the Application of the Legislatures of two thirds of the several States, shall call a Convention for proposing Amendments, which, in either Case, shall be valid to all Intents and Purposes, as Part of this Constitution, when ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight shall in any Manner affect the first and fourth Clauses in the Ninth Section of the first Article; and that no State, without its Consent, shall be deprived of its equal Suffrage in the Senate. # Article VI All Debts contracted and Engagements entered into, before the Adoption of this Constitution, shall be as valid against the United States under this Constitution, as under the Confederation. This Constitution, and the Laws of the United States which shall be made in Pursuance thereof; and all Treaties made, or which shall be made, under the Authority of the United States, shall be the supreme Law of the Land; and the Judges in every State shall be bound thereby, any Thing in the Constitution or Laws of any state to the Contrary notwithstanding. The Senators and Representatives before mentioned, and the Members of the several State Legislatures, and all executive and judicial Officers, both of the United States and of the several States, shall be bound by Oath or Affirmation, to support this Constitution; but no religious Test shall ever be required as a Qualification to any Office or public Trust under the United States. # Article VII The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying the Same. # Preamble We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America. # Article I ## Section 1 All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives. ## Section 2 The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment. ## Section 3 The Senate of the United States shall be composed of two Senators from each State, chosen by the Legislature thereof, for six Years; and each Senator shall have one Vote. Immediately after they shall be assembled in Consequence of the first Election, they shall be divided as equally as may be into three Classes. The Seats of the Senators of the first Class shall be vacated at the Expiration of the second Year, of the second Class at the Expiration of the fourth Year, and of the third Class at the Expiration of the sixth Year, so that one third may be chosen every second Year; and if Vacancies happen by Resignation, or otherwise, during the Recess of the Legislature of any State, the Executive thereof may make temporary Appointments until the next Meeting of the Legislature, which shall then fill such Vacancies. No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen. The Vice President of the United States shall be President of the Senate, but shall have no Vote, unless they be equally divided. The Senate shall chuse their other Officers, and also a President pro tempore, in the Absence of the Vice President, or when he shall exercise the Office of President of the United States. The Senate shall have the sole Power to try all Impeachments. When sitting for that Purpose, they shall be on Oath or Affirmation. When the President of the United States is tried, the Chief Justice shall preside: And no Person shall be convicted without the Concurrence of two thirds of the Members present. Judgment in Cases of Impeachment shall not extend further than to removal from Office, and disqualification to hold and enjoy any Office of honor, Trust or Profit under the United States: but the Party convicted shall nevertheless be liable and subject to Indictment, Trial, Judgment and Punishment, according to Law. ## Section 4 The Times, Places and Manner of holding Elections for Senators and Representatives, shall be prescribed in each State by the Legislature thereof; but the Congress may at any time by Law make or alter such Regulations, except as to the Places of chusing Senators. The Congress shall assemble at least once in every Year, and such Meeting shall be on the first Monday in December, unless they shall by Law appoint a different Day. ## Section 5 Each House shall be the Judge of the Elections, Returns and Qualifications of its own Members, and a Majority of each shall constitute a Quorum to do Business; but a smaller Number may adjourn from day to day, and may be authorized to compel the Attendance of absent Members, in such Manner, and under such Penalties as each House may provide. Each House may determine the Rules of its Proceedings, punish its Members for disorderly Behaviour, and, with the Concurrence of two thirds, expel a Member. Each House shall keep a Journal of its Proceedings, and from time to time publish the same, excepting such Parts as may in their Judgment require Secrecy; and the Yeas and Nays of the Members of either House on any question shall, at the Desire of one fifth of those Present, be entered on the Journal. Neither House, during the Session of Congress, shall, without the Consent of the other, adjourn for more than three days, nor to any other Place than that in which the two Houses shall be sitting. ## Section 6 The Senators and Representatives shall receive a Compensation for their Services, to be ascertained by Law, and paid out of the Treasury of the United States. They shall in all Cases, except Treason, Felony and Breach of the Peace, be privileged from Arrest during their Attendance at the Session of their respective Houses, and in going to and returning from the same; and for any Speech or Debate in either House, they shall not be questioned in any other Place. No Senator or Representative shall, during the Time for which he was elected, be appointed to any civil Office under the Authority of the United States, which shall have been created, or the Emoluments whereof shall have been encreased during such time; and no Person holding any Office under the United States, shall be a Member of either House during his Continuance in Office. ## Section 7 All Bills for raising Revenue shall originate in the House of Representatives; but the Senate may propose or concur with Amendments as on other Bills. Every Bill which shall have passed the House of Representatives and the Senate, shall, before it become a Law, be presented to the President of the United States: If he approve he shall sign it, but if not he shall return it, with his Objections to that House in which it shall have originated, who shall enter the Objections at large on their Journal, and proceed to reconsider it. If after such Reconsideration two thirds of that House shall agree to pass the Bill, it shall be sent, together with the Objections, to the other House, by which it shall likewise be reconsidered, and if approved by two thirds of that House, it shall become a Law. But in all such Cases the Votes of both Houses shall be determined by Yeas and Nays, and the Names of the Persons voting for and against the Bill shall be entered on the Journal of each House respectively. If any Bill shall not be returned by the President within ten Days (Sundays excepted) after it shall have been presented to him, the Same shall be a Law, in like Manner as if he had signed it, unless the Congress by their Adjournment prevent its Return, in which Case it shall not be a Law. Every Order, Resolution, or Vote to which the Concurrence of the Senate and House of Representatives may be necessary (except on a question of Adjournment) shall be presented to the President of the United States; and before the Same shall take Effect, shall be approved by him, or being disapproved by him, shall be repassed by two thirds of the Senate and House of Representatives, according to the Rules and Limitations prescribed in the Case of a Bill. ## Section 8 The Congress shall have Power To lay and collect Taxes, Duties, Imposts and Excises, to pay the Debts and provide for the common Defence and general Welfare of the United States; but all Duties, Imposts and Excises shall be uniform throughout the United States; To borrow Money on the credit of the United States; To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes; To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States; To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures; To provide for the Punishment of counterfeiting the Securities and current Coin of the United States; To establish Post Offices and post Roads; To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries; To constitute Tribunals inferior to the supreme Court; To define and punish Piracies and Felonies committed on the high Seas, and Offences against the Law of Nations; To declare War, grant Letters of Marque and Reprisal, and make Rules concerning Captures on Land and Water; To raise and support Armies, but no Appropriation of Money to that Use shall be for a longer Term than two Years; To provide and maintain a Navy; To make Rules for the Government and Regulation of the land and naval Forces; To provide for calling forth the Militia to execute the Laws of the Union, suppress Insurrections and repel Invasions; To provide for organizing, arming, and disciplining, the Militia, and for governing such Part of them as may be employed in the Service of the United States, reserving to the States respectively, the Appointment of the Officers, and the Authority of training the Militia according to the discipline prescribed by Congress; To exercise exclusive Legislation in all Cases whatsoever, over such District (not exceeding ten Miles square) as may, by Cession of particular States, and the Acceptance of Congress, become the Seat of the Government of the United States, and to exercise like Authority over all Places purchased by the Consent of the Legislature of the State in which the Same shall be, for the Erection of Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings;-And To make all Laws which shall be necessary and proper for carrying into Execution the foregoing Powers, and all other Powers vested by this Constitution in the Government of the United States, or in any Department or Officer thereof. ## Section 9 The Migration or Importation of such Persons as any of the States now existing shall think proper to admit, shall not be prohibited by the Congress prior to the Year one thousand eight hundred and eight, but a Tax or duty may be imposed on such Importation, not exceeding ten dollars for each Person. The Privilege of the Writ of Habeas Corpus shall not be suspended, unless when in Cases of Rebellion or Invasion the public Safety may require it. No Bill of Attainder or ex post facto Law shall be passed. No Capitation, or other direct, Tax shall be laid, unless in Proportion to the Census or enumeration herein before directed to be taken. No Tax or Duty shall be laid on Articles exported from any State. No Preference shall be given by any Regulation of Commerce or Revenue to the Ports of one State over those of another; nor shall Vessels bound to, or from, one State, be obliged to enter, clear, or pay Duties in another. No Money shall be drawn from the Treasury, but in Consequence of Appropriations made by Law; and a regular Statement and Account of the Receipts and Expenditures of all public Money shall be published from time to time. No Title of Nobility shall be granted by the United States: And no Person holding any Office of Profit or Trust under them, shall, without the Consent of the Congress, accept of any present, Emolument, Office, or Title, of any kind whatever, from any King, Prince, or foreign State. ## Section 10 No State shall enter into any Treaty, Alliance, or Confederation; grant Letters of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder, ex post facto Law, or Law impairing the Obligation of Contracts, or grant any Title of Nobility. No State shall, without the Consent of the Congress, lay any Imposts or Duties on Imports or Exports, except what may be absolutely necessary for executing its inspection Laws: and the net Produce of all Duties and Imposts, laid by any State on Imports or Exports, shall be for the Use of the Treasury of the United States; and all such Laws shall be subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, keep Troops, or Ships of War in time of Peace, enter into any Agreement or Compact with another State, or with a foreign Power, or engage in War, unless actually invaded, or in such imminent Danger as will not admit of delay. # Article II ## Section 1 The executive Power shall be vested in a President of the United States of America. He shall hold his Office during the Term of four Years, and, together with the Vice President, chosen for the same Term, be elected, as follows: Each State shall appoint, in such Manner as the Legislature thereof may direct, a Number of Electors, equal to the whole Number of Senators and Representatives to which the State may be entitled in the Congress: but no Senator or Representative, or Person holding an Office of Trust or Profit under the United States, shall be appointed an Elector. The Electors shall meet in their respective States, and vote by Ballot for two Persons, of whom one at least shall not be an Inhabitant of the same State with themselves. And they shall make a List of all the Persons voted for, and of the Number of Votes for each; which List they shall sign and certify, and transmit sealed to the Seat of the Government of the United States, directed to the President of the Senate. The President of the Senate shall, in the Presence of the Senate and House of Representatives, open all the Certificates, and the Votes shall then be counted. The Person having the greatest Number of Votes shall be the President, if such Number be a Majority of the whole Number of Electors appointed; and if there be more than one who have such Majority, and have an equal Number of Votes, then the House of Representatives shall immediately chuse by Ballot one of them for President; and if no Person have a Majority, then from the five highest on the List the said House shall in like Manner chuse the President. But in chusing the President, the Votes shall be taken by States, the Representatives from each State having one Vote; a quorum for this Purpose shall consist of a Member or Members from two thirds of the States, and a Majority of all the States shall be necessary to a Choice. In every Case, after the Choice of the President, the Person having the greatest Number of Votes of the Electors shall be the Vice President. But if there should remain two or more who have equal Votes, the Senate shall chuse from them by Ballot the Vice-President. The Congress may determine the Time of chusing the Electors, and the Day on which they shall give their Votes; which Day shall be the same throughout the United States. No Person except a natural born Citizen, or a Citizen of the United States, at the time of the Adoption of this Constitution, shall be eligible to the Office of President; neither shall any person be eligible to that Office who shall not have attained to the Age of thirty five Years, and been fourteen Years a Resident within the United States. In Case of the Removal of the President from Office, or of his Death, Resignation, or Inability to discharge the Powers and Duties of the said Office, the Same shall devolve on the Vice President, and the Congress may by Law provide for the Case of Removal, Death, Resignation or Inability, both of the President and Vice President, declaring what Officer shall then act as President, and such Officer shall act accordingly, until the Disability be removed, or a President shall be elected. The President shall, at stated Times, receive for his Services, a Compensation, which shall neither be encreased nor diminished during the Period for which he shall have been elected, and he shall not receive within that Period any other Emolument from the United States, or any of them. Before he enter on the Execution of his Office, he shall take the following Oath or Affirmation:-"I do solemnly swear (or affirm) that I will faithfully execute the Office of President of the United States, and will to the best of my Ability, preserve, protect and defend the Constitution of the United States." ## Section 2 The President shall be Commander in Chief of the Army and Navy of the United States, and of the Militia of the several States, when called into the actual Service of the United States; he may require the Opinion, in writing, of the principal Officer in each of the executive Departments, upon any Subject relating to the Duties of their respective Offices, and he shall have Power to Grant Reprieves and Pardons for Offences against the United States, except in Cases of Impeachment. He shall have Power, by and with the Advice and Consent of the Senate, to make Treaties, provided two thirds of the Senators present concur; and he shall nominate, and by and with the Advice and Consent of the Senate, shall appoint Ambassadors, other public Ministers and Consuls, Judges of the supreme Court, and all other Officers of the United States, whose Appointments are not herein otherwise provided for, and which shall be established by Law: but the Congress may by Law vest the Appointment of such inferior Officers, as they think proper, in the President alone, in the Courts of Law, or in the Heads of Departments. The President shall have Power to fill up all Vacancies that may happen during the Recess of the Senate, by granting Commissions which shall expire at the End of their next Session. ## Section 3 He shall from time to time give to the Congress Information on the State of the Union, and recommend to their Consideration such Measures as he shall judge necessary and expedient; he may, on extraordinary Occasions, convene both Houses, or either of them, and in Case of Disagreement between them, with Respect to the Time of Adjournment, he may adjourn them to such Time as he shall think proper; he shall receive Ambassadors and other public Ministers; he shall take Care that the Laws be faithfully executed, and shall Commission all the Officers of the United States. ## Section 4 The President, Vice President and all Civil Officers of the United States, shall be removed from Office on Impeachment for, and Conviction of, Treason, Bribery, or other high Crimes and Misdemeanors. # Article III ## Section 1 The judicial Power of the United States, shall be vested in one supreme Court, and in such inferior Courts as the Congress may from time to time ordain and establish. The Judges, both of the supreme and inferior Courts, shall hold their Offices during good Behaviour, and shall, at stated Times, receive for their Services, a Compensation, which shall not be diminished during their Continuance in Office. ## Section 2 The judicial Power shall extend to all Cases, in Law and Equity, arising under this Constitution, the Laws of the United States, and Treaties made, or which shall be made, under their Authority; -- to all Cases affecting Ambassadors, other public ministers and Consuls; -- to all Cases of admiralty and maritime Jurisdiction; -- to Controversies to which the United States shall be a Party; -- to Controversies between two or more States; -- between a State and Citizens of another State; -- between Citizens of different States; -- between Citizens of the same State claiming Lands under Grants of different States, and between a State, or the Citizens thereof, and foreign States, Citizens or Subjects. In all Cases affecting Ambassadors, other public Ministers and Consuls, and those in which a State shall be Party, the supreme Court shall have original Jurisdiction. In all the other Cases before mentioned, the supreme Court shall have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and under such Regulations as the Congress shall make. The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and such Trial shall be held in the State where the said Crimes shall have been committed; but when not committed within any State, the Trial shall be at such Place or Places as the Congress may by Law have directed. ## Section 3 Treason against the United States, shall consist only in levying War against them, or in adhering to their Enemies, giving them Aid and Comfort. No Person shall be convicted of Treason unless on the Testimony of two Witnesses to the same overt Act, or on Confession in open Court. The Congress shall have Power to declare the Punishment of Treason, but no Attainder of Treason shall work Corruption of Blood, or Forfeiture except during the Life of the Person attainted. # Article IV ## Section 1 Full Faith and Credit shall be given in each State to the public Acts, Records, and judicial Proceedings of every other State. And the Congress may by general Laws prescribe the Manner in which such Acts, Records and Proceedings shall be proved, and the Effect thereof. ## Section 2 The Citizens of each State shall be entitled to all Privileges and Immunities of Citizens in the several States. A Person charged in any State with Treason, Felony, or other Crime, who shall flee from Justice, and be found in another State, shall on Demand of the executive Authority of the State from which he fled, be delivered up, to be removed to the State having Jurisdiction of the Crime. No Person held to Service or Labour in one State, under the Laws thereof, escaping into another, shall, in Consequence of any Law or Regulation therein, be discharged from such Service or Labour, but shall be delivered up on Claim of the Party to whom such Service or Labour may be due. ## Section 3 New States may be admitted by the Congress into this Union; but no new State shall be formed or erected within the Jurisdiction of any other State; nor any State be formed by the Junction of two or more States, or Parts of States, without the Consent of the Legislatures of the States concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and Regulations respecting the Territory or other Property belonging to the United States; and nothing in this Constitution shall be so construed as to Prejudice any Claims of the United States, or of any particular State. ## Section 4 The United States shall guarantee to every State in this Union a Republican Form of Government, and shall protect each of them against Invasion; and on Application of the Legislature, or of the Executive (when the Legislature cannot be convened) against domestic Violence. # Article V The Congress, whenever two thirds of both Houses shall deem it necessary, shall propose Amendments to this Constitution, or, on the Application of the Legislatures of two thirds of the several States, shall call a Convention for proposing Amendments, which, in either Case, shall be valid to all Intents and Purposes, as Part of this Constitution, when ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight shall in any Manner affect the first and fourth Clauses in the Ninth Section of the first Article; and that no State, without its Consent, shall be deprived of its equal Suffrage in the Senate. # Article VI All Debts contracted and Engagements entered into, before the Adoption of this Constitution, shall be as valid against the United States under this Constitution, as under the Confederation. This Constitution, and the Laws of the United States which shall be made in Pursuance thereof; and all Treaties made, or which shall be made, under the Authority of the United States, shall be the supreme Law of the Land; and the Judges in every State shall be bound thereby, any Thing in the Constitution or Laws of any state to the Contrary notwithstanding. The Senators and Representatives before mentioned, and the Members of the several State Legislatures, and all executive and judicial Officers, both of the United States and of the several States, shall be bound by Oath or Affirmation, to support this Constitution; but no religious Test shall ever be required as a Qualification to any Office or public Trust under the United States. # Article VII The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying the Same. # Preamble We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America. # Article I ## Section 1 All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives. ## Section 2 The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment. ## Section 3 The Senate of the United States shall be composed of two Senators from each State, chosen by the Legislature thereof, for six Years; and each Senator shall have one Vote. Immediately after they shall be assembled in Consequence of the first Election, they shall be divided as equally as may be into three Classes. The Seats of the Senators of the first Class shall be vacated at the Expiration of the second Year, of the second Class at the Expiration of the fourth Year, and of the third Class at the Expiration of the sixth Year, so that one third may be chosen every second Year; and if Vacancies happen by Resignation, or otherwise, during the Recess of the Legislature of any State, the Executive thereof may make temporary Appointments until the next Meeting of the Legislature, which shall then fill such Vacancies. No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen. The Vice President of the United States shall be President of the Senate, but shall have no Vote, unless they be equally divided. The Senate shall chuse their other Officers, and also a President pro tempore, in the Absence of the Vice President, or when he shall exercise the Office of President of the United States. The Senate shall have the sole Power to try all Impeachments. When sitting for that Purpose, they shall be on Oath or Affirmation. When the President of the United States is tried, the Chief Justice shall preside: And no Person shall be convicted without the Concurrence of two thirds of the Members present. Judgment in Cases of Impeachment shall not extend further than to removal from Office, and disqualification to hold and enjoy any Office of honor, Trust or Profit under the United States: but the Party convicted shall nevertheless be liable and subject to Indictment, Trial, Judgment and Punishment, according to Law. ## Section 4 The Times, Places and Manner of holding Elections for Senators and Representatives, shall be prescribed in each State by the Legislature thereof; but the Congress may at any time by Law make or alter such Regulations, except as to the Places of chusing Senators. The Congress shall assemble at least once in every Year, and such Meeting shall be on the first Monday in December, unless they shall by Law appoint a different Day. ## Section 5 Each House shall be the Judge of the Elections, Returns and Qualifications of its own Members, and a Majority of each shall constitute a Quorum to do Business; but a smaller Number may adjourn from day to day, and may be authorized to compel the Attendance of absent Members, in such Manner, and under such Penalties as each House may provide. Each House may determine the Rules of its Proceedings, punish its Members for disorderly Behaviour, and, with the Concurrence of two thirds, expel a Member. Each House shall keep a Journal of its Proceedings, and from time to time publish the same, excepting such Parts as may in their Judgment require Secrecy; and the Yeas and Nays of the Members of either House on any question shall, at the Desire of one fifth of those Present, be entered on the Journal. Neither House, during the Session of Congress, shall, without the Consent of the other, adjourn for more than three days, nor to any other Place than that in which the two Houses shall be sitting. ## Section 6 The Senators and Representatives shall receive a Compensation for their Services, to be ascertained by Law, and paid out of the Treasury of the United States. They shall in all Cases, except Treason, Felony and Breach of the Peace, be privileged from Arrest during their Attendance at the Session of their respective Houses, and in going to and returning from the same; and for any Speech or Debate in either House, they shall not be questioned in any other Place. No Senator or Representative shall, during the Time for which he was elected, be appointed to any civil Office under the Authority of the United States, which shall have been created, or the Emoluments whereof shall have been encreased during such time; and no Person holding any Office under the United States, shall be a Member of either House during his Continuance in Office. ## Section 7 All Bills for raising Revenue shall originate in the House of Representatives; but the Senate may propose or concur with Amendments as on other Bills. Every Bill which shall have passed the House of Representatives and the Senate, shall, before it become a Law, be presented to the President of the United States: If he approve he shall sign it, but if not he shall return it, with his Objections to that House in which it shall have originated, who shall enter the Objections at large on their Journal, and proceed to reconsider it. If after such Reconsideration two thirds of that House shall agree to pass the Bill, it shall be sent, together with the Objections, to the other House, by which it shall likewise be reconsidered, and if approved by two thirds of that House, it shall become a Law. But in all such Cases the Votes of both Houses shall be determined by Yeas and Nays, and the Names of the Persons voting for and against the Bill shall be entered on the Journal of each House respectively. If any Bill shall not be returned by the President within ten Days (Sundays excepted) after it shall have been presented to him, the Same shall be a Law, in like Manner as if he had signed it, unless the Congress by their Adjournment prevent its Return, in which Case it shall not be a Law. Every Order, Resolution, or Vote to which the Concurrence of the Senate and House of Representatives may be necessary (except on a question of Adjournment) shall be presented to the President of the United States; and before the Same shall take Effect, shall be approved by him, or being disapproved by him, shall be repassed by two thirds of the Senate and House of Representatives, according to the Rules and Limitations prescribed in the Case of a Bill. ## Section 8 The Congress shall have Power To lay and collect Taxes, Duties, Imposts and Excises, to pay the Debts and provide for the common Defence and general Welfare of the United States; but all Duties, Imposts and Excises shall be uniform throughout the United States; To borrow Money on the credit of the United States; To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes; To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States; To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures; To provide for the Punishment of counterfeiting the Securities and current Coin of the United States; To establish Post Offices and post Roads; To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries; To constitute Tribunals inferior to the supreme Court; To define and punish Piracies and Felonies committed on the high Seas, and Offences against the Law of Nations; To declare War, grant Letters of Marque and Reprisal, and make Rules concerning Captures on Land and Water; To raise and support Armies, but no Appropriation of Money to that Use shall be for a longer Term than two Years; To provide and maintain a Navy; To make Rules for the Government and Regulation of the land and naval Forces; To provide for calling forth the Militia to execute the Laws of the Union, suppress Insurrections and repel Invasions; To provide for organizing, arming, and disciplining, the Militia, and for governing such Part of them as may be employed in the Service of the United States, reserving to the States respectively, the Appointment of the Officers, and the Authority of training the Militia according to the discipline prescribed by Congress; To exercise exclusive Legislation in all Cases whatsoever, over such District (not exceeding ten Miles square) as may, by Cession of particular States, and the Acceptance of Congress, become the Seat of the Government of the United States, and to exercise like Authority over all Places purchased by the Consent of the Legislature of the State in which the Same shall be, for the Erection of Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings;-And To make all Laws which shall be necessary and proper for carrying into Execution the foregoing Powers, and all other Powers vested by this Constitution in the Government of the United States, or in any Department or Officer thereof. ## Section 9 The Migration or Importation of such Persons as any of the States now existing shall think proper to admit, shall not be prohibited by the Congress prior to the Year one thousand eight hundred and eight, but a Tax or duty may be imposed on such Importation, not exceeding ten dollars for each Person. The Privilege of the Writ of Habeas Corpus shall not be suspended, unless when in Cases of Rebellion or Invasion the public Safety may require it. No Bill of Attainder or ex post facto Law shall be passed. No Capitation, or other direct, Tax shall be laid, unless in Proportion to the Census or enumeration herein before directed to be taken. No Tax or Duty shall be laid on Articles exported from any State. No Preference shall be given by any Regulation of Commerce or Revenue to the Ports of one State over those of another; nor shall Vessels bound to, or from, one State, be obliged to enter, clear, or pay Duties in another. No Money shall be drawn from the Treasury, but in Consequence of Appropriations made by Law; and a regular Statement and Account of the Receipts and Expenditures of all public Money shall be published from time to time. No Title of Nobility shall be granted by the United States: And no Person holding any Office of Profit or Trust under them, shall, without the Consent of the Congress, accept of any present, Emolument, Office, or Title, of any kind whatever, from any King, Prince, or foreign State. ## Section 10 No State shall enter into any Treaty, Alliance, or Confederation; grant Letters of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder, ex post facto Law, or Law impairing the Obligation of Contracts, or grant any Title of Nobility. No State shall, without the Consent of the Congress, lay any Imposts or Duties on Imports or Exports, except what may be absolutely necessary for executing its inspection Laws: and the net Produce of all Duties and Imposts, laid by any State on Imports or Exports, shall be for the Use of the Treasury of the United States; and all such Laws shall be subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, keep Troops, or Ships of War in time of Peace, enter into any Agreement or Compact with another State, or with a foreign Power, or engage in War, unless actually invaded, or in such imminent Danger as will not admit of delay. # Article II ## Section 1 The executive Power shall be vested in a President of the United States of America. He shall hold his Office during the Term of four Years, and, together with the Vice President, chosen for the same Term, be elected, as follows: Each State shall appoint, in such Manner as the Legislature thereof may direct, a Number of Electors, equal to the whole Number of Senators and Representatives to which the State may be entitled in the Congress: but no Senator or Representative, or Person holding an Office of Trust or Profit under the United States, shall be appointed an Elector. The Electors shall meet in their respective States, and vote by Ballot for two Persons, of whom one at least shall not be an Inhabitant of the same State with themselves. And they shall make a List of all the Persons voted for, and of the Number of Votes for each; which List they shall sign and certify, and transmit sealed to the Seat of the Government of the United States, directed to the President of the Senate. The President of the Senate shall, in the Presence of the Senate and House of Representatives, open all the Certificates, and the Votes shall then be counted. The Person having the greatest Number of Votes shall be the President, if such Number be a Majority of the whole Number of Electors appointed; and if there be more than one who have such Majority, and have an equal Number of Votes, then the House of Representatives shall immediately chuse by Ballot one of them for President; and if no Person have a Majority, then from the five highest on the List the said House shall in like Manner chuse the President. But in chusing the President, the Votes shall be taken by States, the Representatives from each State having one Vote; a quorum for this Purpose shall consist of a Member or Members from two thirds of the States, and a Majority of all the States shall be necessary to a Choice. In every Case, after the Choice of the President, the Person having the greatest Number of Votes of the Electors shall be the Vice President. But if there should remain two or more who have equal Votes, the Senate shall chuse from them by Ballot the Vice-President. The Congress may determine the Time of chusing the Electors, and the Day on which they shall give their Votes; which Day shall be the same throughout the United States. No Person except a natural born Citizen, or a Citizen of the United States, at the time of the Adoption of this Constitution, shall be eligible to the Office of President; neither shall any person be eligible to that Office who shall not have attained to the Age of thirty five Years, and been fourteen Years a Resident within the United States. In Case of the Removal of the President from Office, or of his Death, Resignation, or Inability to discharge the Powers and Duties of the said Office, the Same shall devolve on the Vice President, and the Congress may by Law provide for the Case of Removal, Death, Resignation or Inability, both of the President and Vice President, declaring what Officer shall then act as President, and such Officer shall act accordingly, until the Disability be removed, or a President shall be elected. The President shall, at stated Times, receive for his Services, a Compensation, which shall neither be encreased nor diminished during the Period for which he shall have been elected, and he shall not receive within that Period any other Emolument from the United States, or any of them. Before he enter on the Execution of his Office, he shall take the following Oath or Affirmation:-"I do solemnly swear (or affirm) that I will faithfully execute the Office of President of the United States, and will to the best of my Ability, preserve, protect and defend the Constitution of the United States." ## Section 2 The President shall be Commander in Chief of the Army and Navy of the United States, and of the Militia of the several States, when called into the actual Service of the United States; he may require the Opinion, in writing, of the principal Officer in each of the executive Departments, upon any Subject relating to the Duties of their respective Offices, and he shall have Power to Grant Reprieves and Pardons for Offences against the United States, except in Cases of Impeachment. He shall have Power, by and with the Advice and Consent of the Senate, to make Treaties, provided two thirds of the Senators present concur; and he shall nominate, and by and with the Advice and Consent of the Senate, shall appoint Ambassadors, other public Ministers and Consuls, Judges of the supreme Court, and all other Officers of the United States, whose Appointments are not herein otherwise provided for, and which shall be established by Law: but the Congress may by Law vest the Appointment of such inferior Officers, as they think proper, in the President alone, in the Courts of Law, or in the Heads of Departments. The President shall have Power to fill up all Vacancies that may happen during the Recess of the Senate, by granting Commissions which shall expire at the End of their next Session. ## Section 3 He shall from time to time give to the Congress Information on the State of the Union, and recommend to their Consideration such Measures as he shall judge necessary and expedient; he may, on extraordinary Occasions, convene both Houses, or either of them, and in Case of Disagreement between them, with Respect to the Time of Adjournment, he may adjourn them to such Time as he shall think proper; he shall receive Ambassadors and other public Ministers; he shall take Care that the Laws be faithfully executed, and shall Commission all the Officers of the United States. ## Section 4 The President, Vice President and all Civil Officers of the United States, shall be removed from Office on Impeachment for, and Conviction of, Treason, Bribery, or other high Crimes and Misdemeanors. # Article III ## Section 1 The judicial Power of the United States, shall be vested in one supreme Court, and in such inferior Courts as the Congress may from time to time ordain and establish. The Judges, both of the supreme and inferior Courts, shall hold their Offices during good Behaviour, and shall, at stated Times, receive for their Services, a Compensation, which shall not be diminished during their Continuance in Office. ## Section 2 The judicial Power shall extend to all Cases, in Law and Equity, arising under this Constitution, the Laws of the United States, and Treaties made, or which shall be made, under their Authority; -- to all Cases affecting Ambassadors, other public ministers and Consuls; -- to all Cases of admiralty and maritime Jurisdiction; -- to Controversies to which the United States shall be a Party; -- to Controversies between two or more States; -- between a State and Citizens of another State; -- between Citizens of different States; -- between Citizens of the same State claiming Lands under Grants of different States, and between a State, or the Citizens thereof, and foreign States, Citizens or Subjects. In all Cases affecting Ambassadors, other public Ministers and Consuls, and those in which a State shall be Party, the supreme Court shall have original Jurisdiction. In all the other Cases before mentioned, the supreme Court shall have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and under such Regulations as the Congress shall make. The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and such Trial shall be held in the State where the said Crimes shall have been committed; but when not committed within any State, the Trial shall be at such Place or Places as the Congress may by Law have directed. ## Section 3 Treason against the United States, shall consist only in levying War against them, or in adhering to their Enemies, giving them Aid and Comfort. No Person shall be convicted of Treason unless on the Testimony of two Witnesses to the same overt Act, or on Confession in open Court. The Congress shall have Power to declare the Punishment of Treason, but no Attainder of Treason shall work Corruption of Blood, or Forfeiture except during the Life of the Person attainted. # Article IV ## Section 1 Full Faith and Credit shall be given in each State to the public Acts, Records, and judicial Proceedings of every other State. And the Congress may by general Laws prescribe the Manner in which such Acts, Records and Proceedings shall be proved, and the Effect thereof. ## Section 2 The Citizens of each State shall be entitled to all Privileges and Immunities of Citizens in the several States. A Person charged in any State with Treason, Felony, or other Crime, who shall flee from Justice, and be found in another State, shall on Demand of the executive Authority of the State from which he fled, be delivered up, to be removed to the State having Jurisdiction of the Crime. No Person held to Service or Labour in one State, under the Laws thereof, escaping into another, shall, in Consequence of any Law or Regulation therein, be discharged from such Service or Labour, but shall be delivered up on Claim of the Party to whom such Service or Labour may be due. ## Section 3 New States may be admitted by the Congress into this Union; but no new State shall be formed or erected within the Jurisdiction of any other State; nor any State be formed by the Junction of two or more States, or Parts of States, without the Consent of the Legislatures of the States concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and Regulations respecting the Territory or other Property belonging to the United States; and nothing in this Constitution shall be so construed as to Prejudice any Claims of the United States, or of any particular State. ## Section 4 The United States shall guarantee to every State in this Union a Republican Form of Government, and shall protect each of them against Invasion; and on Application of the Legislature, or of the Executive (when the Legislature cannot be convened) against domestic Violence. # Article V The Congress, whenever two thirds of both Houses shall deem it necessary, shall propose Amendments to this Constitution, or, on the Application of the Legislatures of two thirds of the several States, shall call a Convention for proposing Amendments, which, in either Case, shall be valid to all Intents and Purposes, as Part of this Constitution, when ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight shall in any Manner affect the first and fourth Clauses in the Ninth Section of the first Article; and that no State, without its Consent, shall be deprived of its equal Suffrage in the Senate. # Article VI All Debts contracted and Engagements entered into, before the Adoption of this Constitution, shall be as valid against the United States under this Constitution, as under the Confederation. This Constitution, and the Laws of the United States which shall be made in Pursuance thereof; and all Treaties made, or which shall be made, under the Authority of the United States, shall be the supreme Law of the Land; and the Judges in every State shall be bound thereby, any Thing in the Constitution or Laws of any state to the Contrary notwithstanding. The Senators and Representatives before mentioned, and the Members of the several State Legislatures, and all executive and judicial Officers, both of the United States and of the several States, shall be bound by Oath or Affirmation, to support this Constitution; but no religious Test shall ever be required as a Qualification to any Office or public Trust under the United States. # Article VII The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying the Same. =cut # This is after the 100,000-byte cutoff. my $bongo = 'yada yada'; ack-v3.5.0/t/swamp/lua-shebang-test0000644000175100017510000000005214023027176015574 0ustar andyandy#!/usr/bin/env lua print 'Hello, World!' ack-v3.5.0/t/swamp/crystallography-weenies.f0000644000175100017510000000052314023027176017544 0ustar andyandy PROGRAM FORMAT IMPLICIT NONE REAL :: X CHARACTER (LEN=11) :: FORM1 CHARACTER (LEN=*), PARAMETER :: FORM2 = "( F12.3,A )" FORM1 = "( F12.3,A )" X = 12.0 PRINT FORM1, X, ' HELLO ' WRITE (*, FORM2) 2*X, ' HI ' WRITE (*, "(F12.3,A )") 3*X, ' HI HI ' END ack-v3.5.0/t/swamp/file.bar0000644000175100017510000000002414023027176014112 0ustar andyandyThis is a bar file. ack-v3.5.0/t/swamp/sample.rake0000644000175100017510000000017314023027176014637 0ustar andyandytask :ruby_env do RUBY_APP = if RUBY_PLATFORM =~ /java/ "jruby" else "ruby" end unless defined? RUBY_APP end ack-v3.5.0/t/swamp/blib/0000755000175100017510000000000014023040526013413 5ustar andyandyack-v3.5.0/t/swamp/blib/ignore.pm0000644000175100017510000000024313770736066015256 0ustar andyandy#!perl -T use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/blib/ignore.pod0000644000175100017510000000024313770736066015424 0ustar andyandy#!perl -T use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/favicon.ico0000644000175100017510000000257613770736066014661 0ustar andyandyh( ƒ~kؠxeط$ɬpGϺֺ$I?֮[If޴x6,*zӁLiPjP@y;3m2uɔDėG}rKv5a__TsǒYAk%:q_)wǓ@qɖ?,z[sGdpHbVЀJ>ׯ{:n,~IohVq,y8 ÏZdd3vl6nf"o+ϸ*ʜֈVf"bʖqrvѯZ[W{泓`h^QaXzEXt6X|fЫq/\ Y9]DmSKM7"R630aKM/>Q;30a=b8 ;30T@<-H4Q; #i'd24Q_Prq1I`f2Uo%l. B`f?G+,$:h&B^JnL:hA )VN*(E g5[!jFWXkpe\O cZC?ack-v3.5.0/t/swamp/not-an-#emacs-workfile#0000644000175100017510000000017714023027176016651 0ustar andyandyThis is NOT a scratch emacs workfile. It sort of looks like one, but it's not. The filename kind of matches, but not really. ack-v3.5.0/t/swamp/options.pl0000644000175100017510000000034414023027176014542 0ustar andyandy#!/usr/bin/env perl use strict; use warnings; =head1 NAME options - Test file for ack command line options =cut [abc] @Q_fields = split(/\b(?:a|b|c)\b/) __DATA__ THIS IS ALL IN UPPER CASE this is a word here notawordhere ack-v3.5.0/t/swamp/html.htm0000644000175100017510000000034014023027176014164 0ustar andyandy Boring test file

but trying to be conforming anyway

ack-v3.5.0/t/swamp/solution8.tar0000644000175100017510000000047113770736066015204 0ustar andyandy~'IMK0)nmӗ M~X7¾ ڋݘ>K(-$银k(X<8 )1, (za`w?=7vBu.Xn;>`eލ}BHO4 (f9yh&*[u26؆*ܮJ ;b=Uj9F/݇_?6V5ZO ۇjs\vCf(wύzZ3raLF8.(ack-v3.5.0/t/swamp/perltoot.jpg0000644000175100017510000023233113770736066015104 0ustar andyandyJFshC     C   8" m !1A"Qa2q #BR$3br&Cu%4568DEFSUstGTVWcefv'(Xd+!1AQ"2aBq#Rb ?4j;A046< <`ePFhfQ  -sa#Y06WgVČ!;y>>b֘zbӎ[[8 *o6WJ$*'l{FL2L fZ1cx MHH p9Vq>ؙSqDG&]XhRi$(heŁ{ApnDfٿ]]rB@Ug:A7Z70@d5 06FaX s7F4!~QRZqm9< |u!T^ u2P&Bq>G0E09(^6Kdt[q7ecHՋCE*I:>zmOfts^B:AB*kT8imGtwR.zZeI !YT-Mﱅ|4Aa&%PV lmI H xM ,[ (6c/: -;Z5,mk±$B7~:Un"_I#,j! c e&MȆ%:qz.9FVg?Խ2223 Mmq2Vօ #8IDqv Jt)1Vt>7RdQd|;Q oW|1Oe{%#3ϒs!_=AHqhpLmmL.H43|FrŚ./m`gebO,}B3Iʡ*>:BF>RR<(Wأ˻aob.i=:> rEn{aapb=N?0?' 5h9"H,mJ ZMoK/=-p.>87/#^>I! UE} : _jq^GyL8 xב(k ,|IԛZE J8򛵴,‡~C"/ۈ(, .7S7;[<(8a;!ŠX/%kꊯgjoB?n ^ G$KT ]`oUCv^ G#+?E|-S˔%yZ9ʼFݭ,rB? 㐞Xģjl"Rm4UqsS!Y]1b9TuK|&m}dMD1;os6dœ=C%x &~0];O+ow͕DF^[HhNßHWӴCzi'S"j'&z];r*Oc^xho[cc.LK,W0~^1m)pAYXl{+10A0F̑D-&cG*H61,=O?1 ܢ͜NfBy2ƭKD,8ܤWC整jKe9@[r%ZhI3t_I#I.!0npb\OXw; # 1ny 0q_eBKS.lv>P?#)f]. /*&~ -9Mb#Pw)?1[^܏maZZlͯ uH0{dXFM.a#4ˬ"6]\?T1PIu%Ѥhb9DfI%[$l, &ىap tc7Κ * X *6AlzBnf oŮ62ƅM 9{"ВI'~-r".5XE7Qxԧ`֥t0͖Py˶eJ:c-zHg 6ԒH ,lOKTk5q.YpI6b8T%m|eJh(0Mcb 0Zf҅-rHx LH&e[|+-x^fqUh縌n$ +P&(5ZS5GҖnMQe4z*ce2&9鉡(| 齔E񫆎I;%hm B(6IG&"lBa>qGL5zT-!̂$[{JiƜsir%hvX؆mxp(wJL>5MX;tHs#10#xP7m ]H#hPTm ]jA@kb7qtm[7[x*HI shHUY"㨙f:J9?KPPlPU.yR,H)%;FŦASik}vgHG mUSK-1ym :DDGYLb*(j{Gtc8GCt4ؒ"@@X*+ꨍ9XR-p}(32@C vhBP6F0O/ L?Ab#igU'1. KmM18ڳR,fZ'qcuL#2>թ+ōR&Tnې< iꑆH[س 0VP!;%d|vm]Gx  8 UT$ n uVfuē 3K7 sVgZ6Ƹ]/Z -y$t==1EƴnmlLT-A(nK|6nm@1UGbTCP$zM)NGeL3TI3i!sb$_=Gz K8e&-%*:yN S͔TA 8ME%nvRwxD>LO[Eތ(\ (TP@-^3:X.ByZ̕'npmIxD6Tb"4g\)  \d ;g\[d`{&Od'kEMQG7ne Vy_D;әN+($2⁹ߕDSKpѿIS cdQTiaGm:̻h-%2"muf] ;c H,<#;:!e!j#tԕ,r8)z 3*4tA}qL+ } >-8J9N;'a-iTJs)N hL}Mj--ڼEd=gE]Q䮂yW6rK^ٱ;`-sK(p<.IePys2Ԓ-u1T\h(mzq9+8o F3oGIRA[Ja3*67FMκlbSDqnM+-NȒ@Trx}WX:;&K½Rwxfm4v4q3nH<6&R#nrajKⲕ+n}d;ue [a7'ƚ ̺Ci,!M9-98;CcG-)Q5|øү)K[\5$AmeξٸPRuGٕ"M`6$:L(, I+I6ߘo WZ͚+F(?MyT!,)eRլ_-M&fj=4IHFٶH$^h,=rRU>LeR6CM@MɰoLߕC;qdZ= $f] :[p =x|ݟ1hQ0ITI-(mMR;:G |9,]*/ylC=8'&$܋E[LZ@fhʊt#SZ$2\Jʛa qnJ&mK7'-i!LW80%ᶶ%,:I=!hR2wc%;CqE=ϥAR)! B k6^g577dĒ JUbFD~0ܣJt(%€]=UB2%>7XjfFԍFSא!%@Y @Si%a̝?a}O2i~l*eg\i Vn وщ(rcګ\3$f~Iˡ Z\'u}%6w.Bј̬ٙ\267Sn"Q;"+Y5SS&`KV|eh6m|D޾l1^&K)0@b\tG5lkRDTr6RtU,3 (%1^vCbe?KsM%s MRbZmx{sc9;5VV{b.rK)W hҔ)wPѰ:.}uz *f=WbfrHҧ.Ju/ݴ0^oTGe|Vx`ث~ \i|i7lJP FtH xC+a:%qT*r,NmU ܡq{q=B?rvL-#'^|S a,)T4rF^ܻXT3MYZtW;ZϮ/k~˚lf;K&Usk)JeM*Ԝgr9s|09S)yioN6Z+~ݔOkf\XJ2 ):Y)CѦ;/Ԕb>2sbVbZeɦj"%ڒBHBR'(5lq&EE"b>~A 0 :ҧm YZIK^hُ{gY3VuY7H,V1/-QiiqH*B\p RD;2Uа}zsff_A53VOܾ6Ы/ͽy_꧖(&h;,KcViW4l V:r8e(V?aIԬuS"2mR~ vO{_-GG8|-?{_-@t$ShU8@{V^9+Yi*q~TsRV%rRlA"̨ ͷBl!K-E6TcB6* ^f^~wK(7#섬L 5:HjMy$[t1ϢÜOrBndIh}H".3Vu%C##Wq,䣁MESd)J;")&(,SXv`8 _;47 Cm )Tʀ"/R|MZѧkLᎉ8Ǭ-7PM0ap=H-ٳ ڲ5>ӼyM曀|4e;ݥMS=91pV@8._жz^ǢUՠX0cI7 XFcQ|jw'rb}O2q%ne.KB)%SHUB݁1I{8([Pz>;J.~IGa uJ_(-&]e,-K Ĺ\G崾!jF%Ǟ|EĘoοOTrꔩ˫.YĺՊ+;R2Xׇk3 ~M2ꔅ8M f6{`lĸ7U|a=m_{5B wm>&;A7ݒ$1VjV:V{J.'41qDMiI'NdkؒOЪ*{I A $D+c$||y%'ڋ2qGb3+)ꑨR>حIscbglg:ay}US*Z)n Ij.r`B GX383-aؗT5 :⛨0 q!O$+O2Z.yQF1?Bk#Wh1agZoXj3o*^1374uW(ҖD)DI7$c(XS[Q1)fg ᰅR:DNi.4DarKR7:S^8Uck_ x"Q!J {SSj;C-p!횵֕*uCHU1xI4W@"B}\ATQ<9!Hzit]K`_Q$v kҥ ~AR])5CyjRUq<2:RrM}jQZ;I.-K!d foijy5=J[8 M& )G8q };BHZߐ 14eZa,%8Hzg 2.:_Mͯkq5.jvrca3(>$S̼ҔV S+WВ!AI.*G^ ?&4W;uTNb) MH2.Kdx"oӼ'0{Sw23NXΕO]6ԦK4T־"nmnSZ8j4ʶ)|ęo1LjVBQ/ k =Ad}U TRTg2 U*;*醜[jHp,լ@'m)Xp#'VdxDyn'%Rbobo!\F`@/0 @\F`@pD_CWrt|s#5rKʚ}NQ DuI]@;cD]j)*QeI 'o 5 Dbf[I#h <@ByʃkQ^6ͽR.b]N⼐dOMJN{]u#u_WAfVɰ[d'6K^!(v~p2C ]+RUNAJt>1-Q .*z+mO3;gʓt(UvY3R lb\stݎv¥c f|?9T6%2 [*DM LI D9Tl#(!&bm9dBz\pC޵߬53db|!XU/ S-B k dШiQq! ͹ã-~Qr7 !~&boх&a(SpMood5!!k)Ut$e)O2*QQIʚ Zq>XӨ{m]:%átE%RzAUҷM˨`hR Y]]D>a0藧ɗ; #.z%c~̷2_ J9;;HSܖ-$$n|lbOa:I[RPVO$v,baG"юt6Ws %]D){AcN8Kazu1)> \r CM@W"*2-d.zany!0IGUSNB#c@ܢάS?1?,0ZeIMf`͕k#3 vˊn4o:*xP4é6[K$lH&;%%hÁPb3bN`RU)R`ja;88[ɌǓXrepiKKi6>Ȋ)*-(%;a&\}8:l@DtF84^q%%*) p"ӌ;—{8HIɶrF*,]c*Z;Brb[v1ocy{'KUhXzW 7Nvwߓ}^CV ̤uݨ;,mH?I.lo J/Dut?RU8IV8Q]0q [?~WiE)w)<|  ٿ׷*OIjE;iDcGKSfBdg7K2˳_E'V0/TJSe< }?(fg+g1kh|][ ZZ*́TEȗ,,1kh YG ZZ+g8P%WD 4>5c ůբg#C6AƏ8W ůՠ~Qw~#Eڏa#+N%gԏXcjbb>##i+H|M?I/&8I NXVqhUT3iBƒiPBJA;wnEVnԄhv^D·Prm<iX*{b.*ePԳrIEH$P;"xm^";fP6Y''a꓋7P˩m7ILňX1m;c(E(e4]V^ cf@´v9P&mn5o\JF1 #>1_"G5-WUYs9QaV>Q{7 yƋ$x9ZӲϘ?>;iO&)UWf(4ܭMTl% Z׹D 7Ƒ$nM9=?=yG}>6:{1QN%]ŏT.lMXo^+c7V/2gU˞bXV|lNy//քkWJBL' 8:gʔꬑ g [Ԯoew G"9.B`~hY%BŰnF hFԂ]sZA;*͂T-r|<:qвTZ.uYvnIm m5[?4m>xG{Cz&)'G#ɇBTsamw鴾͆u0) $0i/2:%FF7PK%iSH=IL@ kG(L$*p$]J<Jƴr#-D'py WJ7!iANTUe1MQhfPESBKd-oˣA%u)+XP+)x3I"QqØaYia'09%O1C 1k^IdG0AԬBHR5Hfصe͢[\fý" na R,a4g)?0M}S3!+alR|yf@Ƭ)2uQ_UGǾ*f*o@RX(8U*RIRF6[+xf/=.FD+ Bl)y%+hL--;O":bU^ZKt(Sj)ijm3*NĆW)@XF /cɤ.I0b1 P&wowܓ QJ~|R7JB<ȴäXL60r*[x9):H[ [sd6V3d7ÃxFnWW6E̝b zb|Pά-IdNaecЁO(+Ο${3&t mwҝhjl6)'w.gVkwRb&yj_sXneO˘jzӤق=+oeq!L! Dle/kQD-LE)h|؋|۞=xl_.d_b|(9Y+ʗ?d&{(_":C>MBs+4WdiYJ:xR# c]xPY!j2a`zyGFׄn$/!ڋ`JK*,8@"9XTC#uz9 ^l.YML ~c:p]PCJA|ϙk'v%iɩQoq -i6=Rҵ`O(a~PCtĈҤHR;7dT=Ѻ7aWi!~I)PvkAEķB[xtTJ'5RSOHJI>0Gj!:yh8E&FPb?Oғ!-8Ny9.(ߟHqq{=2V'%PCmBRw7 lP-Xn\@ Ja(^3&M,) %%׽"꒔;XF‘{ܛ)Cg NۋAȩkL89NKۆw6t*p%nMBGw5qTeeN,o rn!jY_u!twP,V ΐ n$}tBqܽ_]=Kcyb]H PZ٥RprX_0K;7U+n} I!G0<W4>FdE& fY_(t>[L%֭vqhTRb &b[!a IRwHE0%WWFlWu*UJ{CK0zt 6n>*+yzel=yꋍݞ6"] {Û99Ioq,mlbb)T!hm,t;X4IJRh-5P32q{\}7Cpj`ttgm 0S %'|=L0:j#(`^3T&hl6j IROE1+ -E1q.=74`tWøSkRYs r9!iT)lI{z7Rw!s6D~"1 9A Pdmesr׏]Hq(o4S)Ru,5Rruh ᯪIn4mE!u![+CkF]u&rJ JmpS  Ԧ Y$$ˑgnyAZPVH&дx4wRIaCa [*_h\Z=yOiSEsNi!18F/Oi'Xa嫍34aZR<IgX P'Vmquu٫ȗ4=<Ǒ(HRVLvodfpRg\LċԎbuMQdO)k"xl Z,A0-#?d1OS!WH>˫[9O42jeSL` U}ZMɨ DkFN+@#6nVJduɇR4Y"p ]w钋غwP9ՙb\72ۨ|/*>nhSx|#-;o*̬Us!Z Jqor<"μ1@Ì:imI-̨*|#O e9.-47PRqOdI>&9833Ⱦ)lomT3ag} -&(i͜ʧUͪu2rGuD)o?Ou=J *<; 9#fyk%,%CPz@U `B>l}x D( +?Žd샕C_i=Kv4쏝Co鲋o?N:©?ŽY;Y)6n 8yvRb&ʔHQA>h+F뻘 , Vvs^B]iH׼'mСtX*ЋjM2d{XCFJ, @smKIM9ƉbtMAjjfHf>JBiE("J?oTG(ɢva#[ZlGErs Q by@|$PT>mkHN9:99CJIW22{ sOP+LKO.AC& 595OW |3()yx8W~q6zgZyD%)y`$e,dPޞg_+k"ʫ[|QS".'vlmnf;Vp'+#_+Yb]Jc)K UJy_̣KԋNU{(XT:kӒҫÉZAԻA?bfItMl~1V˗TI Y>cS u.$(mЎ܎vKtU8b_@;h.4nQn2!XzJ|KHaGu&Xo 1MDT;N7oMOW33/ JRl?ew3e.) >OtQp9Dr"u)e7;f&vU iy'~3ݔ230JI+Nr d9m;sL'Sz]RT 4ۈ(c[_e۟7{e$qߙs˄V#3JH3,!eUM ]Poec a w-1:ļdܩyħRt;(b8VLi[.[x8FLۿ?|?l5)=1 w ; IJJ+FM\Knca'&Ow䉛$ᵝ?\ 2GYd4y<ECrϾ66)@y`ǫ 5*~1+'oAԏ,)e{*P8z;*pz[q2çesl锉E(+[]@ܘzzmm*-v5a*d [7)I>w7-^iTjXMBx%v\M:j4I!,jߪ|=>T|x'3MENSd?*DH%O!sS :Gx:dLäRkǪiAq%rvo=ԚdMR,~t2+;uJׇ l& êkQ yZ0'rvU8D)2~襱3 q4RU{U[ty*]RTp'd麄ysWeJ]q%mΝryt|e^ Xna[98>e)z/j*>7KRp̝=&m3m+ӭWj'7ꃼY+Š|Izjpõ yoOA 6ioߜ2LMbW$HtҥD$*%$jֲnO)R;х,1D :9c*T@ PѨU 7ܛF\ɽmJ%o\:6X1Bl.eqޒ,/U[qQ-#zNR&I3"g2i 6eˁ>9C+֦ +C@S:lkSl I1I[mvNe£{rZT9JHd{qʫQI$p"dskxNκ)&$KV76H,Tl.Ʀ ʲeAE*8y=_ˌ8E QW6t.;Į<\YlyAs9LIL, YI7@ǃ:zi3: rƒf+4%IQ&pz]6 *6ݥɲ۳0-rIg)r+;T?zh_feWm8.$/h ڋ]DsU˅;CRg&_{q="辕Xr_O8(fG aĬx-cP)˶SPyOVjg2ckˠWC/qWW[m"0У}:m~&hEf$=:M4B;׾Nj;zÂE-УbGQR%M9  2YzT TzT!;Z'oS Z=d,`3moZ,zvR,7Oɋ:㋊ H۶UrN8tTDD҅2IMTKg~vVMzYvq6P_%$cƃMU5X3zysSͩ\RkԳ6eL9apä3Zhi& ϩD6ƈBO8(ABdP`%;^iR8RXZkx$LiJyu:6x'`- 쒡ԞÅ*] ޢDnL2.Ók :4+* B+ 2u'kkJ"ͤZ$ǗUZ6ĵ\[[Ra+.{={UMG24pĒ ؏?Q,?Mt0 $/BcŊ8mSgK'劏 ͪ*eMyߤ'qz`)ijZS`@7muZۘ=k 0sab[ؘUMAuá!E({͆MƒO+Ôqĥ#rldC.RRnB3ܓSJR,ض[s"-Jj"v"%FTۡE zbfTN#+f"ujcDVZEoGNf8|5; ɘ$X ;. %r0 YI*>B4SE6 \`aؒiM9e$hUYUM:SWuJ:qY8E3Q˸IR,A<א.M!I.Tve>taۆȷşW9E\YяHeLo88`OTm#`TF!>_Bz/um@1yt4%'3d ]uFc C\7#D")yYRw1^b,RB.L1a, 8nG\JPj ɚL32_Ue [e=16mG{p2Cx'ˀcO$y$O/& /a0/}C6Bҵ /zzyFN9\et]#E|q(kZQ0OUt-||>>ݮf% X"|Uʈs{0. V{13sn2.֗ Z?"3$<ǥ(\g~Ռ=Q;g@ՁpjmZ8 @⃓G?ڤ|~{8:Kj#9^ǧ0!@nA0]arz&8`\կMmoI'kI)fZ $͏Np0Pjz h|pY?۠sGQ[W𠙬 m ˌ E ?ƏB/m?AG kt ܩi:( AA4G!B9NoX%k ezXx%Cδ =]7˜ [W<]kz!%/rgM?k gPcW ՗]Q 8G|y{Wyq_…]BrY\?V'5-Bj-uukP:vл€RH;r}s>Nh-T]NP6R:)* G4dUTm6}a-= qR:M]?+43]*yJnZ'sl<|"쁕V\5JI+DXouW~'**Ms61>FeaL7mZ)h6|$-x ͇8jlz#(+jn5TzTmG$GTZBr]6Ҁ ]2>..LZRz{hoJr1x|biBٶYCkb)D.>7]"ln|Z36aH^n 359h*JN5$ 7?!XpRll$]~vqi*Mi R?]cz*c$#RQ +So~fosnsΊ֧M8\yG)O'"Љ?H@I&KoEBtNثrĘl4 &2:11-x0l<4Jo6̹h]:e~0Q KԫD/ȑ"ļ$IeDwaa15A9ZCNˍvPثꏎSJ]JUbPOgad):: 6IPm)'Y4g1*r7<Ǔ>|:Rܫah 嬍L4=T%^WtF(6Q۳SUFSEٝYVU邋Om>O]>fHiVYš䜩UiMT@ѹ)/rNIms J=.!œ$s|fj`텲LZ#H&&Z_JByA[xGEP(T/H|7ba;_V19$#1-k(aS:A t>QqSdQ!Oz;=`=w82rG?-UejDA6 mܛڋCi_fpN"eBT|Ru;0d6P3 hyWYY]%dyD2juv]RD,V0IdeZJٙvg x1قO@Ra'f.&-3?e/L{~U~3̃cfN@ @ @3 @cf @#S1k0<Ȕ˻HRN1djo2nIG3IAAW,~{񎫨`o~sFI)S/%(YeJR,>_xF237vkc6 )--@K=GSHuAE<_2NJ* j;۔Ii(%X[(ʔiX{=-:uDSv\R9VT'@raa#Hڢ-Wbw TM߫~k!c>+#Cl]HN|G0ާ!heU< Dh34TL?a)>+p[\YwN)mJbn{ DmbS^v1:@-zQBM&P*ƹ6nQip 0=eR@8aVxϧngJ ۧHQ('SyĤ/rbuZi6蔍DA r*12u3U.z#_sҦ-d![8>Ǻ#0Z|ST RgdS@UWDut}Zm ,a8kGK:9,ahC7L!9#CYMҜPvIa>S0.#³R$+ٚd‘iM;(Ǡq.3s71FzbVffB1J.NNiRuhZlܫa 4pIy]|*J/6쿡M$ŗZTVAQ)1;E/5:30!j^a]S\ҕhֵ]VP Ovl416I^c|5*U16̿-—BRPIH*F;<+4`j0|gpVv]%ͺR S(ShԥjNv]ggdϘ똑>-@BNuO(3l- FXnP'<꽅(ZV Wḍ28_֑p89e;[`env*|M*Tf_,.֭t_FhvQS\*nOa4$leYxn,$@_I7=32=)Oէm}:G{8:";Ifsd~1,=V0C:=qK@'S:6 !A[X8߱1|(8w7kx8A]2#[!|0mtĈrWs[|UPUS4ٵҕenn ZAWO&soix U'(MjZ}5H"K:MA[kOht\,(ʜU c$q`lԍ5\iVʹOz .c}q\GL@3S%YTS"^BRβ@&;;~yS"KR(]jU!N--A ]KZ W;G;doھaA30/1z=-6H.ii Smպ{xZ؃ 1]?fbN۞gZJҕ%I!ā6P:,uZ<ߖA{*25r7213:hEP]Dt)ℕ^0ڙW:Sأ FebaFBzMRfR M[Bo+6SEFn3bnaXٳC\5U ފJGV'%#?~Nc\NSSwR*rj342eI`ҕplF`Ϛ̺Pd]fjBS)*BARt ~M&1 ꅅƛA3 i]QrU씴$Dƙ-F~,n[i(&g]BP'Blt^L$(r+E6h6IyI;w0 Fo OV%X#*6夛sx/%j{'zsA*;KVQo88:,# >5yG}%V7QÌ49"'>d#4*xkXItxVId`w|aY[ێRe`r_){GS}#֔d> ! cggk%r%EuGOժi3!RU/5J]d-@Z^+Iex_s3*zy ŕe"14_0uo*.IhVbsOQNZĈk:+*DžR"*Z틹Il0ulދy)-#0DVZ,ifJ/5kq ǔbD3X z aK}Пp*Sf/mly~ AI%f$݈AK I2{{ }7ƴD-uR_Go*3O'UmZLNbHK Hd~fԊX\ItOLюӗ8mn_u=gW3eotjyX!|0{*¡=1RZR *b.[qEjmh"]#tJE)iVh-OO+3rQ%s2xjIyD_@f]tTg ̵\hifY)܈٦J$ 21S&fPwUk)R*a<\m@DerZl\TStq=IΣ_rbƓݗp,*𲂇QmQ|),@\?Mf@߬W9_:*Ѹ!*^,y9P hm{G;/j"JJ4֪rRt`GeLCmǥRM~J#0ě-8I@\mTH{83j $9UZli$mv}3Kink铳ꔖLJ:aI8%@A#czҗ>=ŎU)݊ڞz[%JZ8\QU4Y X}bZc#0+a)L][sJzEe0Ԗ%Z-,6Uέ:H٧.&3e8_ZDm95ĦH"Y.˅` ,(OtgNw1f/Uk[ci$k5,ABJu8$pu 7)}>]1klĸUrӥ0FinKY/KBI@CJ.H hn|+ɫϰąnzMt"ViOΩ/8J[~9׽1>`vx970sxݤlio7fwfo2v-?50VdL9K/I[ZL6@ ғ1NMO6&UܷMNC Լ)|d-RHYy,cKfQ:<ǽsNښ ٺ\3>xlˤM#VZ}ȀS Gڃi<Ԣ>!4C8jvt* SEA$@ B{|>ӹNŔԷߩIUІmRAP%y.|kx;.kfqf+2:# Χ[ptye%5ٕmb W-LlS߳eLIM7Ӵ'7#-a Ĭ4Vq< <PuJP NMG+>]2fc40&*LHxI* 3ml ސ#H4;B`yjW ca1cb?)8rW&uLl}3N%.>5CdRPuδPN]hdIvLe8Q6`Fī)J[wX#4T2L6CL}Yޮ%٥+C2$kn<$pKQ{5j2R`5а<# J.9IL%u6xr%. _:n&ZQ,KcȡQ9#ͫ+n؁o(6RCvNc pE>ޚ }?5+O5oM 5)*p +E *5ιo+@q^\Vƒ$ĘH"!MEԥAO(`:a8v;| R#j#uT Q+Kh sʊ:q(qI7ͬG8BL0NMރ+PUr^VqIKj$@ ͊,(W~fd[R EBEN!6F[3فK{PM*]*L/Fء) NJ) ) 2XF I,zDZiJ 8ZT "L(% zKm#! .a &LʅeAOK|;'0&B:C5G4I+R*0I*US{5SQ>$1"3HJn[(}G96;[S-94fXp\M>q>1Y)=):?A&&dSd\K~K8G]A#ƕq'@ԄV;}We̪IaV Jkj|0ܣmx(7R.L-Oq).KRH.@\]&#^"116B)JI9GTye$TT4TbSp_YDFEYҶT.DCp_m[edMqq۔qol\-t+ң)C鿅?m")CiIhx)]h쉉G)Z1.;;3MU3fƂ'i m=p<81sHљwe9&M6񊧳bvE7K6'x]OQvwRNa/Ouu=v:}VTIJJAQ;XFRVrfut[rZYAM+S"i`kQ몷U(`Xcx=33Wk,g'V^V!Yߍg%/5.JYVҥ2Xq%a*I)*@ b9={ ;DvM˷*YyRy a˯5:.cҢwW3bb>l Ƹ*\IP봆 `! hlp" &\gƘ{ fyT3"e֚ ZgRY}.F헹#+!Hs 8bjq]3y"x@GV('uo<?wc,UmV,ɇ4@\!)"$yc D~SwTO8ysN-8~T4ɗ_mG[D3/rocl=6P%gJkRu'”O]BciN-t0\{fV/p D3;9p~bfB1rMV(0@P*-%W gdh_b<8RÒAqRX &c%ۻ!q6mp YH|%?A6ekVs{PS4D$'/$H#_ 8K$ /4;T*^|͚PױaƩIP\oB2n{đbM(̬-!BRT6 "8.>RJ 723U=(;A\[KMN6:*BWkJ=\ÊbJZ}B@ l:R Igc7s"LWq\?nBiԅ E\yL˩Vf3)jh{K)Z4Azըk퉓^z1̝njtȩ^Z) yMT 2G59( "ji$^ H,(t7{BKLBKE$UAze9_ITJVRI ?j3U]AP$,Aֈxv՘.X7.+z.v[!4ÃBR4i*hԢV@7"V+'.).R%9GKl..)J$!:MXi\-P/1l#4au_ISN llXtq :#clh>KTMK]eʫGAly{މʟk_}r*|ѓ*\a.[_[o 3/uJxennW2R!ɦmGΥW$)J)Ө3N\auR\S:zfij' ɰ@<쒾s8 MƓXઊT2B*i`-)[ Vٞ=ԜfN86Qe.Q 4BCr\()a X ֤܂A gc\}TLƞVrnV_kBpԫ#Er<섰#AJ ;%8F#m+yθr~cf)5b1.̀!q|jۂpXU_$&A.)A:Ltȩ1#:\'s8}b",;m15>8 \_/tMݗӶS"\(nL} 54\'E:@펍b]L?5C9fuiJQ0Mcs{3QJ@Ĕe] Q4K4TtE#S1]״ZQ4@ԯ;T_.O-'&VMVvmŪF͢|s{5I~i[НÖR6a¤B| k Mz0CI ~ xA/LL H_n U@! lV`P&ÄlzŎDD;q@OKCMVB7#3R. ˙efY̩W$_c-HɗZ8>crG*kFLdH_m?gFrEe%i8u FģMi;6*k眰eInri/6P&;jQLwb>&I։6QӹODKl^#H!V9%b78(iґE7ɀW%ީ$vpm,G%* b]agPQ1qVJNUkxVwU' &\$@tE+ppT‚veDarg\TɽʝR7tn̹eƪKޚ$ϜoPK"i@Bla'rlOD#-QAG'fͯD#/F72I1_#ѡ(eZIۊD+.e*YR+BLGxD4F^] "cֲmGCot4=%߰LjO7Ӿ),qaR%mF&d G)Rq 0 %JS5*H itY:ok}QКZQOvxq~)Ir BABB[ToNZǧj2J*?XO̬#RdeNJ^MerRsm%_ii)[kB JH) (Glwo!b}u Q($PTɨkAj85.CG*q+А]]ֳDG21$p]^)hbA:{%Vdp>ZZ jR{3,Ĕϔ'Xƍ,Ka֜8}4&Ԋt#W0m*Y ^yF}j_l?LDRJi؎ܵ˯T CvBܷ(~ >B>vp*ޠ7NC*O;DXmJ-daUejM,(QP<#&d͠$}mUat@~jF^NSKeVi|˲@+ B. 3ؕ86E96\FEĤ 3_C[*$ΒцW2uIHuxWT Gm<Ϣ?tDrMIZKZ71 j a?O<L(^i#Cpq@ܩ(R "TY\}I{JB(zD)6IIѤz6'mvշ-t aT,F> @ F, 0 @#, r @1q F$qdO ̷,6HIo+Cj6K0fgG'죋!Wy^dc)[ih;THPޛ62aFi,@#IOJl IjNѪ_ÜXgY#trĂVVct *"sHEiƉ!%9=yPLj'DG>Y@EL60|^ti/DdcK}efC)e?*/q&Bmh^ iScI[)u /)R7 mEˀiRpДp$-j$Y¥$:|olQ RT B1gÎXPslP0gk"R(@ { =~=PR)O }H3*䈋JLч˼6M['S\`2[? I<,2srϺ'5Pb"dOڨm.qڿP-75؞q1ƉS9otW.VѬP)S&r;hEŽZdAwgCz!SlK.U&Pi*RJ+n'52Ґ>\=;wQJA v1q{cDܜ)Tlpԥ|cl !59%A}.YRڔCi],!e3d4 NㅦemH~@TD iUsh,:itjdk^Y6%5^Vj"@J[Ry}esrvhƸ*fHebiA,JAn;ko$g\E?? ~+v}=q]+9>({ynZ'=qYrh9+^~2#i? C_xqGd?|9mz]m>{5,R&Q٣eݿaA˯|qAnLTvWX"˯|q$|×^ߛ[8K'd?Prk[=q|olm$p)ʻ]{[(Ys|qlO e%sq}>BUK̴hysHC\,hP |aL \)hce5wnp_5 l&l&H up:|]ȿmPn O_GG_|qi;v$A8L9rr?l~R~O|q}Z6\)hʕvSu'[,G}bah "&95 XԊURB\Yos9qh4V VRT*$lSSV0 侇O%Gn\c~yG`ZԞ鱍Sz꿔'MTY<MylyYxJMSGVj :`)#g$qcԛiCe_DѦmox[1( s;`yvyzPeœȦ*+=('𽆽BRVBcK$YzeC0]Y; QE:n}u&e]y!}DI0r>Rzz[!:)a!@b :_8y9{`l3{whۘm{0MƶX}^20kFB<WB8*q& 0 d,.Vf"JWshxa4fogPKf{Fě_PRS!A5G ^ )#TV"|Zt˔B2 rR ;@H'{F1|>AẗH $zCZaH쏓wRؑu\Lߙq-d){TU=2MaeJmn@RM6xP6xJ$dB70T Yh [5R)l}AT ?*Gtj*q+QbGds: H]2"_,)xy[l$JYpb6gbI*,*~imGH֘T: h4 ~7l+Tormnn9BD۟ N,Jy/#}nmezB}6в5B(.P xRIJA;s# =BG8\E\]@)wS2Ni\OGF>]$_h2$m4Wt8=PhWx/ΤT/6 O5*FpVJLk6JU;!A>*wܓ}^Frl #0H$}m*e fy]`y?Q'O29r k6,[8=aY%d!OkߔvYrMयV #ѲMo{F-:ƁD1<`do ׍o7܌.ddfϫ1{ <[ N 7M'w - lHZlj>6Hv,t%SdhA'xT#RyB($#6A8Mkp:AH+)/D*#}Ʃa ;(C6M4wt$I>PkIjM+p3Lxw'$(PnOr҉V%ZɎ.-si>%ouI?"phVAoU|fJTXB&w&%I *&LzyXZ 5IZzӎs0}A*uK2xM6UAUL O1֑ XJFE)Po%W1 rXm"WZ[j|K.%9(g/L5|k8wXl>0XS)EEE_DJp~eI]P浨^&*65<a{/QIeU=2J/3NDjR,pOuIRja};ĆQ2E,?O񁠺SɜDfʬH8{FZg$dty~rMKWv2@34ߩ%e(eIq##/#|rQM)YCz) u~oǵ괧iN/AmIiQҒ9Jq ւ[sA^ZjjJ^RH7hJ6TQQ'V+fd4WA6"$k%3Ei)UĒ5f[)uP7RdXkWwVWKh!u-6~_d-R0,HH@=*w)7TU2 _rtg.yjPH?|pK4[JV`믠y6t9;i兣 Fߙ2*'U}H@Cѧ*t*V9HÏwSkZH2{yGI.J"yI)s`(J*}EltI*]ٶvW1DAqcD$zObcPx.ZQlJb?(㑲_DXMP‡ZӽMF Vt6ԖiG!dd2tE>¶D$y*+b73cȈJ^W L(mP@Ⴇ*txoN$纥XymcKl>6@U*ä2}M\)R0[^p_lG^]r)JrG1O/?q.j5g$ܧ< 4ƛXm X0eht0b5~}^@6`{!Lg#* Qrr񀫘N5_xaC{-DܘJw&X I|O =O  AY)W.1)~`ښ졢!JIl7E빎F`3NOtsEZїB֋?% MlZC]=V2zdӤ*]A_%<*T\{2 ;0ձcΗE}UM`s7/-RGֱ>/%Yy&5-"0dZU4FYHͷ1 Sx#,}ȰX&XkE5[h6R;$٥v1)ɺeGg%*WFI|,N/c;maɉ`,(\'^MK8ڊVٺHoENA' D'}$_{y6-| m-(60uBRMnjZ:gz4敠uCwҦI#$څ~o[`d(nAx&s\g,Gh~Z>lZs(II ϐ#$\(bSt_ sVi `0ṟuRyV{94ka4V|Is30n|uQ':#u$tQM݊ۚnN GV+#iRέm%'Inbyq-L#%ѥ*QwJ+ғЭk#װ$!He.[u\ʠlZRZ ßğX!s,wxɽ-z$=-'twSYnכS _JU?X+q{ox2cMx%Oh'iu.^J~Wf[ٖel@q?Kkp,<76]•_EÒqh[km,XMƘKܸ|%F;"q='nq[ ڀ  Iŀy;W(%'d(^Ucb0OHom UF Ξ0L>#U!&f)mnۀyr):[kA [M-'nQ/fa[ƇqhW0H ߬w0O&F v(ƪ_HYyR־]` 4V1mw8fǺohUqXXnk6$EECLꍦx@=as]>~Ub%%*^ Y2R6AaUt^ֈ)~҈epu 1J0"Wx{Ģ8_Lx}+/o#EV)4w(i7t1d"~'UpG\rT)℄Ljve<)iu19NLo"UUd(ڏ5 r1kB±#e}䶎n-gJkOkRw>.puvN<xؘdJLF)UiUQ 9.md&q 9zyu ƇwLu6M9 H0'Җ Eq%{~qLwN[J 9pO˚}f!A7 (mH­ ΜKT%3RVxfy)36l" ֒ʂ=fy/1 idJ8fFe\ѝϠ58Vqiw fl)e6{Pb/Q4(yZ-Yd6겶ĵ3<&VDSkN*6Ju㍽s*}ݩd*iFm|1ͼkòOX=TbHlL 8lrij(LJ7{fbrjZ"R]IhOۢ.Cuר \=O&UHA,nj[l*t0TJ1lI'iTW|"??(-uJԮ!ugIQV%*vC!Lސ*/HMnQg#j%Z/dV3A/) IiHKf2/DnfK{ϩ$$D+M X# US3B^p"YV24?mQlwR/di?0Oڮl飘nvml|c IkA)Tt&yohU 7񸲆+P>QP #`A $+l @)bH|$*p -,mnH@ZwC=[%\XHƝaU8(8?8Fr@xsH#]8œXZ)U .jK͛)$=6*d&8mm&M!"2q)͹CrbFhKS]3n\!IPbyEE!J{l<̻YQUt?DŒwtZra$l~z78sbwO;`arb='twTy\PRY#bW}enWqgh~0Be͏ni`U8aخ}U*l\P¬;3qfm*H8{J6.(gdIgGio!PX_l>1sb4S'd] &_R5IJt+_a4 X?( R Ih˛"ƽjh_9($ x{*rExNaȩr\НBŞp@ ^+DZ6`2rzR[GPHhN@J%WxF eB=>ENcI0UTVE+<ȵ)A5mX^-ۑ 7&*Sr\ +E};-={m<=osDzdתžlw8ocC=dm1I\'L\(BnA&0O|LپF 1n;7@<;6DsvlWQR9mfQݸ{5S醢<=X»5$ )=[VH;5ST75+i;U8|CR݋FP C MOJtDjX}*C}/Ja(K::%xjG3 H`F^7UO}a/m/'S` SZ=A@nYl2n&#RuM4]IB)\CWjߐ?[?(IڲeV?\'}%=AɇPtj_!ǵi#}+4-NYc4 ĕ`z)ٖA Y\G mJac"ʬx"?ryDٞ2masmɴ|4v`Rd6ulGRaVP[n$)$xEA'찴^3,q鏦6lYR:|Dwc8AòBOnlͮmsߜnbd64< iY)%Ĺ)"GXP ʰgEІBR)@ JA,MF%XAͲnDXy#!-^4и Jo ;)E6cmn!|ea-8N3Źí. nRHÈ0~{f T9!R@7HZB2 TEHDj-HH;)O%t٤[cخ_ 2]J[jW@<*m /K<=Pҭ͹xJw1ķX,?U8 Xƥ{^nmTeN\H7N.Љ=s%ŨPT|U'3ƼZ5R< " XFhzƅ60iM|#-TyC!$#VT랇,sC2qKdT]`x@M*nf$Id% ' iϲR OgDAN*nS6C[vey8%<&ҕ֫'a %FVA>PvϬE1ǡ'l(XI[i@n,9B;mmD+0dӡh pm`LlZne6n$I"m Ԑ1ĘyBGѸiӷ8raIV< 6|"JBoV2g%N lcaktӵqu#,7Jaq{kHI\)D E $x±86l$kssyY{M=⩩:DE1UrN+% ED'E5u0Scx=Y.GGzmuF!_6ȲPr5ةZvq}9ok0caEhC.::H k|߿H)YM`׏0Q ${3Ғd05S$}P|s\?J@=#~2UC2@a-z9TTij;팡?FqE;dԘOtED54w )?3\#t${ocE=ha}~jTa lxakx:yߝ" dKl}x)G90YloP"Xݚm}-og$Nԥo!+m$\W02(jN}`(mI_/jP jBv( ,YmM3sMqsFu\ {+}OAlw)dxT@HodR'2WZ9E[Fhl`A0;Z!xLJ5C/k0dC 功w1gL"n}>j^R6--IZپLMX B,P|L!^L;1,SZ@ iL$oȂl.G+F aK_dL\PpX38NY .ܓlA%'F$~ja!{ZKskwS r Y{Y nb,%Ê}0Re)Ŏ ]Je%BEVEiX y$y DO2GRGP WKϤD_'ͪ\d4AX{à]e&&VT!R{bu 'eZJtJ&ȂlLHl|#0rjL9'6y'T v%&fe.mDo&e3+;2[piIRe BsI>1ChGA@MIe0x)G"$+wm]tVͰt_N' >=6)qyRS~i6'H|LL_#y%jX!-_97.l1kAmQI)%DKX:b^p^\Q)$NA҄(yu)yO2"dTE=eA/bU6\#kre:NyD6k4Ӝ2yItn 7D|RCKIft ObYvρ [+ %7%kKhFd92!Ocг`H:>Wb5wsNcx9'!rɹ0Z$* ]{#PoхyVZOq`E!pEiDTa¤IHDlMkii*}=t ~!"^]LTY%h3iV_WV0 u{jq&3έɱǦO)CZ#;­'if0ʒU7G|֕XBӥ`49~ZwR T&U4œ0ԲT~ A"쀥X۫MËΦƓ -'(&K"Jv~U _ |"Й5UK-}Ǚ~p5mgPqS*ah@ࡲwP7xWfKgZ^Ee#028ҡ:&C,AA?x\)ԋ {aڹiHiK H ۜHW]xC$X,E@S4BFɤUwH)S#11VqIQj^7+ $"iBUqv<}GjEͯ6W Q„w`* (Ѻa} VbZAS8b]TOS }s3hOxÎط1ĮT*e 9u=qPLV3^4Jd/ H5#HdC%p[2rHyoO'BJN̂M};(@/JRmqn}6<&>ML\~>mb'Z֩Yi OIy}VNX |h>Vxً_J7O,JHm]aӨC+e!`)$y1f1Bf0Ul608tRȟgcm nqܘ{ U$-A~Fqߝ)'Q1.@A6Ѳ) 윫-W0IM䩲&Iqn:G^kTb} &U=qԼ ]HMIU(YM<2JpI}+ҿ}^ N !d(e~]}OCm@pݺxm &":tÒBJV D3 ,hy@nZ<L/֔tuO-E^'xF)`}8pb^X)G * 77Df $Җjݣ%! 8$l J5fxX<0dz5]oPi)[ZX0Zy2az5'kB\i%9S7/Nk^f9'&[ SQ’ on=b-82[. >;o<Nη.ZluA(Dyw/(S &eN҂R.r|zGe&<)_E8p}.*m8ʚW_1LILueXM *|4k\'-}GmIn<i:=8G[97T]eVhf[=+F|ĿTx9ʵʗAdH _xx裙j[K5,osART /Kp#ϔ9ӱʒ'WD;%a]>i"mZ %mG7/U7ey7tLL<~_\ 9ىp9K4ʊ(#45:19xiVqIslIVRZ%I~1IN)0YaVZ 0dj\gkμ>ʘ[ u=^]tYulXؑ%529ι3N̩U['2r@ =H[XSR%u0G||uZY#Zh&)F#ʺgeL TuTTB=UQ8 2a̢ `m=R,d9G_(N 4дHMbATr*A(?r~0i99ZeU4m4u;)zx]*geK- ".Zee+ $%hx*vgZǔtO&xFQfGK-iH)/SoA(q@ 26 ǚex)"͸onpeDZs*%BMvȹ<~&O%q2]ZA[ +$@'t ^cnÉIRg[m:7{Pcک ir2r ˶@%)PVLGA*6 Qsc0fAAe&ܠh>( 43c`6jAFncU(\FUɌW;\~ϹË/KWzU $o ".?L3378pD()V?hOIMVo _raA'SoydTq9$z8fR]N"mm-`T|R=Ư-H;NiJA)TJbp@\gQ[M8mQV \W9dp2*C! >=dr4-[\7n$yy *R*>h(4:Z BDh 0V['m˜Aat. =!Mi CfvN#IU݈|a7H<=t@DJf8.B_t gWhR%Ϋ˼ǡf5j\\@%8l\wz`!;` $$jedU M%CۜsƚfFEOD-ٯ\Sԗ$eSa)T=Ek3 ^ BO_YLӠp3x}$T͹Xq-NB6:ãW5s)U(ZJlO uJ|Jmj p咢P<;f<*PMZZthtUHIf;8B#7\1#Oas(xbSGCj'0oL%z_̧I96p!9%)[Jo/xv`_iZd?|v=?PF<ЇЄ~Z4G#)jdM<xS*ߐNw((Hq[e\/o *iPՔ?I.IpGKM0@ۃ31"!i!Q!GQ."Hl `Sstp $%J#Ae串v[ii8LeC؛ їค˼Hc3ڳ,tjAF&U(`7@{X؋@< 6i8 ʅ2]ZZiZ̀f%Tk2%q!DɎ 1#u<6ԶS.ujMaӷgk iJ U0HDԻy<&jM>ön[o>Oú{3_.))yKiB.=ښ\ўs^A]Tmt'aF=K@t%][tGi=Zfku4 Owğ>zN?3`nOH¥n"dHѴ zǤܹ@MϜ/31K8꒧)@qTT7Bd]iLABbi@Zx˛Cq%X{ Q5&iMGyk^ix%WO+ Bp6jR;wFC\Ȕj^u/6~}_0q>y ʷ T ZSQ6bjKL:Pd;tH5.lz+,Xې66KO:W[hzfd .ۘH=tPIȚG]Y*̀SLc{+b.0l.i'HK&L% HxVZPD.zp\6VGѽG$5k&4y}o1Go8mI-XA*iAثvvOԧ-h\笮Rb'Us(~D?!y)(rZctaCIQC iee7GS8v×Q-收Aϭ_OUa6QDٮRyĠMT~@_ zK C#ѰZy)k?m[%G"VUtA~4''!*c T8~-,5&hE*BLj;EZ:Cg.{S-ri هҊTSOG~ \:Gjs) S].+-2[q-@sNP`!18?6!N*F/\o-jy:҇؎p7Hɲ/$ý{u< xNF5t0x Œ 1F(wbl+dܛ΋:7=ce8f1(Dwyj h5Ϥ όhɗqŨ%IR (.]e)uJ8UU+MI!- p~C9ݡMbna۟GNܽh`µ332aM>%)^)T#Oyňބ;E :mm$Vg׈sCuzmO~G-G9ꚛ'- zZRzk/ 8rPg0'FRR&Ir.!Ȳn4i}nFjNlJ@@H ]ȹi&&7nbUkrr# Q;³Np r#B"SYb*6z`UAm_x6m  ) Vց_GRv[SJKb7`'n˜zka:}2mm>Ѹ> r #lo̳8Cν-9CĒ~^fXYNV-=sZG 4p}G,]-Lk͒|oq<||㯒9Av mā";eʮ$J$Qe`+]]C-(zf)آWT8:Cd{[Aώ: gP-Ϊ\A6yĔ9ĤÚmVBүX);mY̊V^r2Zrna. 7 hymޣnmUR-O;C1mR3Fp{f~1u(nDFٞRԫnA>'7ɞgQ1OJ,/A;ķ`eTd *"@,l8eԭRm+:c x5LP䝭S]y֫HV(RL_ҨĻM'BxȺ̹9OLfP<؟iITgkơd)B:ɵ}ѮVȟ9T pFV8:n'1;L q f6;մce'~`6xP^=*LuE'Sl{~ԸCJEZgg-Z5@:lzA7nwMZ4V!Z;NhYMX0]:!1ï;Ƙl*|ac#ԃh\ ڰڊ^fP'^sm@f%8U ZrrYuo !7C6 V˺4cKCYҥ G߼JأL^,h RTv=.)9{[-.;GDeIL(!* l |?0JԮA$L+-䤳, h40$عع#%\􄩵,rvbUŨsc;$ķNd""S^r_;(џ4P}V#E:bܯô9/*0]]=h@(GHJե$Zv1s4I)ڔKiT?}--\ə9yFn6|ic݄VT2ݞˈ TSq@B䒝FX7BFƁi$lnC[k聹Gz"&VaYɊ33tLdCU'"3PNfyl,2(BD Z[Rj*a*ijDYZZJS*Z=l9ٺ%ZVO}rsҎhHZM‡ce}n<#'gUoG4 Ė#a>gٲlc0/qiSg+e$hY*iˁ}e3TɥәeX@<)y8_˶f2K,:څҤADsxs άsUSQneEz ~I.K֏nʁbwʟ<щ+?jVհPxۨkRP>ݜmZi5KvNi.k:iZMҡquF TթšUslF1&uF 'v0K0Mc:@H 5 xjYYqD ͖8"٥nWB9}~hMm?K2<6b9.JTM"Q#؞ᤍCE^wa/%dOm j?pM+1pKV2}Ө ؏dHIh&vYμuT Rئ5's܁iy6ҙ g\NFkl;\O4|ߦ6#-2`L&Uz`c@r^T˪\b׆&h @`۫#>OΙ0UÐZ=csaBxvĵd~LIo\ܸ:#͙DIr/JKEH& ;Z;[ƪJVv7e']ǚNn%IȷYK%aI&?|w;N,G5y[H LH $m`إ/MB,7'Um#@3<H$)Rî4\"qGV;1* wjD~DS90БlJqytTMwy t`l1i֝lRAwMq=񈈛eG-1D#UX#rM azSg> aCGkBT@:Q%p~/UҦNg)>S=GpzPD4e x>/M es*& 67ir=}W,rLû|CE 9S'[!mJl)dA^Z:q<6fy96? )ۄF'3+E ka' ;)*J8S`OA{|cO"ߨ>Ry-crIq2l;ާ\JXm(P-›\ u啼rE̙JC`R\3.-Z;arSӹ*UƁ;t m 6RR@{RR7S),PЙ3ry d\ m"ֹ>]a3[7Bo JTZXPiET"۬"[i "zٵؤÜj) W0wRo NċyD8&jD>zn[[@̄&sM:웩+hI,JrZX06P>qTwlRֶjt{> 0MkuDue47bd0uԒ78{7] ]USH$ |"38?JTWX$XYe U疉T))=8F֛d֥t+|_Q3 \JVѫ^(ʻֱ_KʹǶѧ%8&TztxeCmpV92xv_Zd1Fc2*v(М!-M3P?>?ܥ%fP6UǶ;R[4 JOq.ե .5RS2-x%}ۨ B/pE"=hJVb9MMV X^+P ?tGX_eJaJq6P(a|嘠Qے&@ƒJsh9c=nА|L6gMut1b:Wu${It\s_%Ft'){2*Noԥlc.JKEޙoz2TjiBg*3+qVQ&'^4BP1gNvICI0@SI%k>3iH.*Cr$YPAo^Κ2Guˑ jOiRH,:1z3ߤ_g?P?{ gM&]g"]vM;Ē ܾ軦s(6>*5n.V0n~0wMl~ ¸)b<*m1gPmd—S͹32[ut[V9oY1|0 rUB)[Z;PɲUsӧ\pTHdfтvHQ ^F($ʌfjMRy`eGs &6 CQƥPfzs FN`Fd+ǜ{5"z"wɋSz:TZ$^8|ch*;/%T=J/.l~gYӇF7%$TD4⚔y}u"9J-t$\V_R@QU6ՙ¡.rFj8TzH8zltӛ[!lR}ٚaJ&)!$n]ձ@V8NWNvv"s{@x(]eK0%A |ӓ<>dߗ:Vҵl0⬌M)soM2ʼn^ؐS(}N8.W븴4nP-h%=ԁkt<( %_Yf09Q%D 2_FƑu"S῔)d;1/{tSIji7 옮[XnT&#ժK[Z If%YcZRM￲b $O.L7!#H>•}"xel-nLuDUpHI%JF'ZͅX --nE>wK̬ aҎΐ G8Pm mP0 ֕<P:mzr5QulKp^IvfIi7\ZpiQJ %\(rIl2oMTJ-~]MR®v(SpYJK6䑤s/ZeGe$Ii݇[/\drࢽuT͸ӡƔRAyyŻ[^JÑYԀ,O( m(w^>2dQt垸1Mz$ױ95H'h܉i\M)( WTGF;ş{KjV! LjuemIR4^$哨ovjIuU9"Z-r]>%2 0%8z "MEc9F*:o y??2 J SbY:r>xv_LǑRJԆܝ&Y61'L8=Q%{1)-\qf}1;b+Y.!CY}*1Kc$6b#XNgZ҄; !;66dbEa 11MM ^];x8O쵟 WĪ5Ғ boMXuФ;u:)e{#3bBXp(86-F4=ћST8jXFhq Nuōna%i!4wT_~]*TjuC(59uTq}n|[`W+̟iR2qG-JnaP EmC/yw1:~*R&p^&eRJ3&WmAx94Paiԙfh:@DY}ɊԼe+Wy-F]B H"&}HέЬ *^4*70C:M!R\0 ᙗ]ˑ2E!"хxbq^ZmxйF5xA@ x76Џ }T H!w ׬ƉM3;M xj 1NS)m5ͳ"m𤡪jaycѻOQx ϗ㩰:4`a-f#D0e'~Cxd$ ('&5G4{,4@U% g]yIj㕡e ( ڢ1c'U;Xem |ZeX ˶ &ВQ KɊRZ̪SSǘVJ}$R}Hm|Nǩ2=_rՊuhˤA&ܗ>J R.,wn.UC$)Ek7iHB.MܽmmPN}R,\D✩8 R^؏ 3P\ˈYZ;r"u4CgѸN`..|Aw,Xt `$\D&OT @~yj`pO IF{>7Ck<. ɢ@2S CBqn^^l&::R ¹2 R@;{#F*;BVU |%${aKJP!yD}8 K&ʁ lϿqH N7:6 H 5"(Ys*JO ^ׂ_% I|@#o!h抋^)'T[ K3^;s/ӛz*NJnjFqTIK: #\_911jMIh3 E;G(̙WWtf찥l. 9SZa%VP"ֈcr7i|a&&ĩ03c$KJ 4dY.6x4A؅cii/,pN$DOIfii"FiTQ=R^îw*&mF9oTSUWjL75.)qHtPWTRܲI6j?WqKe}dU%QIRE㝎(Ddc򞬰osu~&t(,l5{Z98mh18[RMϴC˶6JJ)<)uEQGɺRk2k7j>Rv+@'KJ5ye{(qҢ 1v,he7QяӘ~,K@lJ?eK+ í[J*MʺP6cȓ۔m(M-͉0UҮFBw ۔&y.~h]ڋxUDM;b manɉQdܑ=rH*;Z%R.,nNu!*q{IJMQ]V(K ]LMm Öۜ&.4\lnm:-wxh HZrrbfv} lODQR fZIHX6 V٠È:|85\CHϑ<A"f0i;b$y*pX[P>N}®FSx§@8moV]"Ϻ"U I0AhJ6: t2sL8u` w#-3l Xh.:1U-LN25;°h~<(N/3h^4pZ#w>B)!p0C6|`f4-:rq&*$ߤm+mcs s=L1(‘kodǼCK+5>*uwGCL–~B"4Jg-iŸtjNV &|3 ! MÂBHT44dR&b:Hc1h)W,[]U\j >=D6bfZqr<ʂZ}%BX6ͭi:LN+tl2q|i('FT@(la½ i5%C0֓k;f5 h{{xKfBmXiÁonޤ%}HU -t GxyO"( VmlTtLz֤AVO8D0[y{bw-ܥ ؔWIGi,M]IS^ Tڡ^ܺm@B4zwIb$eNdz~}#tM;u>I#.zH9dyA[Of1Y,g\Īu 9ە9>1TJAŎtd= DְVmsiΕU :R?c厚#s=}۳txFtB|I? >%86Uڐ*r:F%u,m,?4Ů܄ TXRS-@7!Bǂin2RW%"cz0mPہ`r8!xެ6Ai)@=mEg5QJ%V7xh1ԛ^JuêCca\j).Wemah涙0HSI>Xn -6!lLQ (BCL ΞdEٚ72b'DɗR06(A̼bVl:6y6!(m@.mrxƘYmB IYSby匳~˃0BQsfL eY!.1kRjSOjMSeW5齏Q|g\:5"7̄"fFNMÒ Q/)(y幁5wTuHt%Cmo/*z]nNM:{ z+`R58Sn;-+Vy2zm+EO-XMYN| E# ack-v3.5.0/t/swamp/notaMakefile0000644000175100017510000000020614023027176015031 0ustar andyandyThis is just a plain old textfile that has a name that looks like "Makefile" but indeed is not. However, it should not match --make. ack-v3.5.0/t/swamp/perl.pl0000644000175100017510000000024014023027176014004 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/fresh.css.min0000644000175100017510000000013213770736066015125 0ustar andyandyhtml,.wp-dialog{background-color:#fff;}* html input,* html .widget{border-color:#dfdfdf;} ack-v3.5.0/t/swamp/sample.aspx0000644000175100017510000000037314023027176014672 0ustar andyandy<% example.Text = "Example"; %> Sample ASP.Net Page
ack-v3.5.0/t/swamp/c-header.h0000644000175100017510000000052414023027176014333 0ustar andyandy/* perl.h * * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ #ifndef H_PERL #define H_PERL 1 ack-v3.5.0/t/swamp/MasterPage.master0000644000175100017510000000012314023027176015752 0ustar andyandy<%@ Master AutoEventWireup="true" CodeFile="MasterPage.master.cs" Language="C#" %> ack-v3.5.0/t/swamp/minified.js.min0000644000175100017510000000006313770736066015431 0ustar andyandyvar cssDir="./Stylesheets/";var NS4CSS="wango.css" ack-v3.5.0/t/swamp/notaRakefile0000644000175100017510000000022014023027176015032 0ustar andyandyThis is just a plain old textfile that has a name that looks like "Rakefile" but indeed is not. However, it should not match --rake or --ruby. ack-v3.5.0/t/swamp/perl-without-extension0000644000175100017510000000014114023027176017105 0ustar andyandy#!/usr/bin/perl -w use strict; use warnings; print "I'm a Perl program without an extension\n"; ack-v3.5.0/t/swamp/swamp/0000755000175100017510000000000014023040526013632 5ustar andyandyack-v3.5.0/t/swamp/swamp/ignoreme.txt0000644000175100017510000000000514023027176016201 0ustar andyandyquux ack-v3.5.0/t/swamp/Makefile0000644000175100017510000000156014023027176014153 0ustar andyandy# This Makefile is for the ack extension to perl. # # It was generated automatically by MakeMaker version # 6.30 (Revision: Revision: 4535 ) from the contents of # Makefile.PL. Don't edit this file, edit Makefile.PL instead. # # ANY CHANGES MADE HERE WILL BE LOST! # # MakeMaker ARGV: () # # MakeMaker Parameters: # ABSTRACT => q[A grep-like program specifically for large source trees] # AUTHOR => q[Andy Lester ] # EXE_FILES => [q[ack]] # MAN3PODS => { } # NAME => q[ack] # PM => { Ack.pm=>q[$(INST_LIBDIR)/App/Ack.pm] } # PREREQ_PM => { Test::More=>q[0], Getopt::Long=>q[0], Term::ANSIColor=>q[0] } # VERSION_FROM => q[Ack.pm] # clean => { FILES=>q[ack-*] } # dist => { COMPRESS=>q[gzip -9f], SUFFIX=>q[gz] } There's not really anything here. It's just to have something that starts out like a makefile. ack-v3.5.0/t/swamp/pipe-stress-freaks.F0000644000175100017510000000052314023027176016347 0ustar andyandy PROGRAM FORMAT IMPLICIT NONE REAL :: X CHARACTER (LEN=11) :: FORM1 CHARACTER (LEN=*), PARAMETER :: FORM2 = "( F12.3,A )" FORM1 = "( F12.3,A )" X = 12.0 PRINT FORM1, X, ' HELLO ' WRITE (*, FORM2) 2*X, ' HI ' WRITE (*, "(F12.3,A )") 3*X, ' HI HI ' END ack-v3.5.0/t/swamp/fresh.min.css0000644000175100017510000000013213770736066015125 0ustar andyandyhtml,.wp-dialog{background-color:#fff;}* html input,* html .widget{border-color:#dfdfdf;} ack-v3.5.0/t/swamp/perl-test.t0000644000175100017510000000024014023027176014611 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/CMakeLists.txt0000644000175100017510000000003514023027176015247 0ustar andyandy# Not actually a cmake file! ack-v3.5.0/t/swamp/perl.pod0000644000175100017510000000007714023027176014163 0ustar andyandy=head1 Dummy document =head2 There's important stuff in here! ack-v3.5.0/t/swamp/perl.tar.gz0000644000175100017510000000072213770736066014620 0ustar andyandy`0 J[k0_qAnph!amYC&J"FIR{]sɖ#Kp䲫{ڪ =˱C/p=v<;-+rL>?e \1XQ)JiǺT2(E8}BO<=]B{eq</O~2t ͢;6Cǟ?] N;p^o_z5wW\\wٵfBTnM;v\r#X'o BCsNf2I*..E}7*czQlYi_vST%6_vSN;9$I:&4!.Ld+O- tAAAA  F(ack-v3.5.0/t/swamp/file.foo0000644000175100017510000000002414023027176014131 0ustar andyandyThis is a foo file. ack-v3.5.0/t/swamp/fresh.css0000644000175100017510000000013214023027176014326 0ustar andyandyhtml,.wp-dialog{background-color:#fff;}* html input,* html .widget{border-color:#dfdfdf;} ack-v3.5.0/t/swamp/example.R0000644000175100017510000000001414023027176014262 0ustar andyandyprint('hi') ack-v3.5.0/t/swamp/html.html0000644000175100017510000000024614023027176014345 0ustar andyandy Boring test file

but trying to be conforming anyway

ack-v3.5.0/t/swamp/stuff.cmake0000644000175100017510000000003514023027176014640 0ustar andyandy# Not actually a cmake file! ack-v3.5.0/t/swamp/options-crlf.pl0000755000175100017510000000036714023027176015476 0ustar andyandy#!/usr/bin/env perl use strict; use warnings; =head1 NAME options - Test file for ack command line options =cut [abc] @Q_fields = split(/\b(?:a|b|c)\b/) __DATA__ THIS IS ALL IN UPPER CASE this is a word here notawordhere ack-v3.5.0/t/swamp/Sample.ascx0000644000175100017510000000014614023027176014613 0ustar andyandy<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Sample.ascx.cs" %>

Sample Control!

ack-v3.5.0/t/swamp/javascript.js0000644000175100017510000000016614023027176015220 0ustar andyandy// JavaScript goodness // Files and directory structures var cssDir = "./Stylesheets/"; var NS4CSS = "wango.css"; ack-v3.5.0/t/swamp/perl.cgi0000644000175100017510000000024014023027176014133 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/perl.pm0000644000175100017510000000024014023027176014005 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/00000644000175100017510000000017214023027176012573 0ustar andyandy#!/usr/bin/perl -w print "Every Perl programmer knows that 0 evaluates to false, and that it is a recipe for DANGER!\n"; ack-v3.5.0/t/swamp/Sample.asmx0000644000175100017510000000017714023027176014631 0ustar andyandy<%@ WebService Language="C#" Class="Sample" %> using System; using System.Web.Services; public class Sample : WebService { } ack-v3.5.0/t/swamp/sample.asp0000644000175100017510000000020614023027176014475 0ustar andyandy ASP Example <% Response.Write "Hello!" %> ack-v3.5.0/t/swamp/Makefile.PL0000644000175100017510000000024014023027176014457 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; BEGIN { use_ok( 'App::Ack' ); } diag( "Testing App::Ack $App::Ack::VERSION, Perl $], $^X" ); ack-v3.5.0/t/swamp/minified.min.js0000644000175100017510000000006313770736066015431 0ustar andyandyvar cssDir="./Stylesheets/";var NS4CSS="wango.css" ack-v3.5.0/t/swamp/#emacs-workfile.pl#0000644000175100017510000000016013770736066016076 0ustar andyandy#!/usr/bin/perl ## no critic This is a scratch emacs workfile that has a shebang line but should not get read. ack-v3.5.0/t/swamp/perl.handler.pod0000644000175100017510000000002714023027176015572 0ustar andyandy=head1 I'm Here! =cut ack-v3.5.0/t/swamp/incomplete-last-line.txt0000644000175100017510000000011114023027176017270 0ustar andyandyThis is a file with three lines of text but no new line on the last line!ack-v3.5.0/t/swamp/options.pl.bak0000644000175100017510000000035613770736066015316 0ustar andyandy#!/usr/bin/env perl use strict; use warnings; =head1 NAME Backup of options - Test file for ack command line options =cut [abc] @Q_fields = split(/\b(?:a|b|c)\b/) __DATA__ THIS IS ALL IN UPPER CASE this is a word here notawordhere ack-v3.5.0/t/swamp/service.svc0000644000175100017510000000007114023027176014664 0ustar andyandy<%@ ServiceHost Language="C#" Service="SampleService" %> ack-v3.5.0/t/swamp/c-source.c0000644000175100017510000000341214023027176014375 0ustar andyandy/* A Bison parser, made from plural.y by GNU Bison version 1.28 */ #define YYBISON 1 /* Identify Bison output. */ /* Contains the magic string --noenv which can be tricky to find. */ #define yyparse __gettextparse #define yylex __gettextlex #define yyerror __gettexterror #define yylval __gettextlval #define yychar __gettextchar #define yydebug __gettextdebug #define yynerrs __gettextnerrs #define EQUOP2 257 #define CMPOP2 258 #define ADDOP2 259 #define MULOP2 260 #define NUMBER 261 #line 1 "plural.y" /* Expression parsing for plural form selection. Copyright (C) 2000, 2001 Free Software Foundation, Inc. Written by Ulrich Drepper , 2000. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2, 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* The bison generated parser uses alloca. AIX 3 forces us to put this declaration at the beginning of the file. The declaration in bison's skeleton file comes too late. This must come before because may include arbitrary system headers. */ static void yyerror (str) const char *str; { /* Do nothing. We don't print error messages here. */ } ack-v3.5.0/t/swamp/notes.md0000644000175100017510000000004314023027176014160 0ustar andyandy# Notes * One * Two * Three ack-v3.5.0/t/home/0000755000175100017510000000000014023040526012304 5ustar andyandyack-v3.5.0/t/home/.ackrc0000644000175100017510000000000014023027176013364 0ustar andyandyack-v3.5.0/t/internals/0000755000175100017510000000000014023040526013353 5ustar andyandyack-v3.5.0/t/internals/ext-filter.t0000644000175100017510000000117614023027176015636 0ustar andyandy#!perl use strict; use warnings; use lib 't', 't/internals'; use FilterTest; use Test::More tests => 1; use App::Ack::Filter::Extension; filter_test( [ ext => qw/pl pod pm t/ ], [ 't/swamp/Makefile.PL', 't/swamp/__pycache__/notes.pl', 't/swamp/blib/ignore.pm', 't/swamp/blib/ignore.pod', 't/swamp/constitution-100k.pl', 't/swamp/options-crlf.pl', 't/swamp/options.pl', 't/swamp/perl-test.t', 't/swamp/perl.handler.pod', 't/swamp/perl.pl', 't/swamp/perl.pm', 't/swamp/perl.pod', ], 'only the given extensions should be matched' ); ack-v3.5.0/t/internals/ack-version.t0000644000175100017510000000055714023027176015776 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 2; use lib 't'; use Util; use App::Ack; prep_environment(); my ( $stdout, $stderr ) = run_ack_with_stderr( '--version' ); is_empty_array( $stderr, 'Nothing in stderr' ); my @lines = @{$stdout}; like( $lines[0], qr/\Q$App::Ack::VERSION/, 'Found the version in the first line' ); done_testing(); exit 0; ack-v3.5.0/t/internals/noenv.t0000644000175100017510000000434214023027176014676 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 3; use lib 't'; use Util; use App::Ack::ConfigLoader; use Cwd qw( realpath ); use File::Spec (); use File::Temp (); sub is_global_file { my ( $filename ) = @_; return unless -f $filename; my ( undef, $dir ) = File::Spec->splitpath($filename); $dir = File::Spec->canonpath($dir); my (undef, $wd) = File::Spec->splitpath(getcwd_clean(), 1); $wd = File::Spec->canonpath($wd); return $wd !~ /^\Q$dir\E/; } sub remove_defaults_and_globals { my ( @sources ) = @_; return grep { $_->{name} ne 'Defaults' && !is_global_file($_->{name}) } @sources; } prep_environment(); my $wd = getcwd_clean() or die; my $tempdir = File::Temp->newdir; safe_chdir( $tempdir->dirname ); write_file( '.ackrc', <<'ACKRC' ); --type-add=perl:ext:pl,t,pm ACKRC subtest 'without --noenv' => sub { plan tests => 1; local @ARGV = ('-f', 'lib/'); my @sources = App::Ack::ConfigLoader::retrieve_arg_sources(); @sources = remove_defaults_and_globals(@sources); is_deeply( \@sources, [ { name => File::Spec->canonpath(realpath(File::Spec->catfile($tempdir->dirname, '.ackrc'))), contents => [ '--type-add=perl:ext:pl,t,pm' ], project => 1, is_ackrc => 1, }, { name => 'ARGV', contents => ['-f', 'lib/'], }, ], 'Get back a long list of arguments' ); }; subtest 'with --noenv' => sub { plan tests => 1; local @ARGV = ('--noenv', '-f', 'lib/'); my @sources = App::Ack::ConfigLoader::retrieve_arg_sources(); @sources = remove_defaults_and_globals(@sources); is_deeply( \@sources, [ { name => 'ARGV', contents => ['-f', 'lib/'], }, ], 'Short list comes back because of --noenv' ); }; subtest '--noenv in config' => sub { plan tests => 3; append_file( '.ackrc', "--noenv\n" ); my ( $stdout, $stderr ) = run_ack_with_stderr('--env', 'perl'); is_empty_array( $stdout ); is( @{$stderr}, 1 ); like( $stderr->[0], qr/--noenv found in (?:.*)[.]ackrc/ ) or diag(explain($stderr)); }; safe_chdir( $wd ); # Go back to the original directory to avoid warnings ack-v3.5.0/t/internals/config-loader.t0000644000175100017510000001747114023027176016271 0ustar andyandy#!perl use strict; use warnings; use lib 't'; use Util; use Test::More tests => 28; use App::Ack::Filter::Default; use App::Ack::ConfigLoader; delete @ENV{qw( PAGER ACK_PAGER ACK_PAGER_COLOR )}; my %defaults = ( 'break' => undef, c => undef, color => undef, column => undef, debug => undef, f => undef, files_from => undef, filters => [ App::Ack::Filter::Default->new ], follow => undef, g => undef, h => undef, H => undef, heading => undef, l => undef, L => undef, m => undef, n => undef, output => undef, p => undef, pager => undef, passthru => undef, print0 => undef, Q => undef, range_start => undef, range_end => undef, range_invert => undef, regex => undef, s => undef, show_types => undef, sort_files => undef, underline => undef, v => undef, w => undef, ); test_loader( expected_opts => { %defaults }, 'empty inputs should result in default outputs' ); # --after_context, --before_context for my $option ( qw( after_context before_context ) ) { my $long_arg = $option; $long_arg =~ s/_/-/ or die; my $target_arg = uc substr( $option, 0, 1 ); test_loader( argv => [ "--$long_arg=15" ], expected_opts => { %defaults, $target_arg => 15 }, "--$long_arg=15 should set $target_arg to 15", ); test_loader( argv => [ "--$long_arg=0" ], expected_opts => { %defaults, $target_arg => 0 }, "--$long_arg=0 should set $target_arg to 0", ); test_loader( argv => [ "--$long_arg" ], expected_opts => { %defaults, $target_arg => 2 }, "--$long_arg without a value should default $target_arg to 2", ); test_loader( argv => [ "--$long_arg=-43" ], expected_opts => { %defaults, $target_arg => 2 }, "--$long_arg with a negative value should default $target_arg to 2", ); my $short_arg = '-' . uc substr( $option, 0, 1 ); test_loader( argv => [ $short_arg, 15 ], expected_opts => { %defaults, $target_arg => 15 }, "$short_arg 15 should set $target_arg to 15", ); test_loader( argv => [ $short_arg, 0 ], expected_opts => { %defaults, $target_arg => 0 }, "$short_arg 0 should set $target_arg to 0", ); test_loader( argv => [ $short_arg ], expected_opts => { %defaults, $target_arg => 2 }, "$short_arg without a value should default $target_arg to 2", ); test_loader( argv => [ $short_arg, '-43' ], expected_opts => { %defaults, $target_arg => 2 }, "$short_arg with a negative value should default $target_arg to 2", ); } test_loader( argv => ['-C', 5], expected_opts => { %defaults, A => 5, B => 5 }, '-C sets both B and A' ); test_loader( argv => ['-C'], expected_opts => { %defaults, A => 2, B => 2 }, '-C sets both B and A, with default' ); test_loader( argv => ['-C', 0], expected_opts => { %defaults, A => 0, B => 0 }, '-C sets both B and A, with zero overriding default' ); test_loader( argv => ['-C', -43], expected_opts => { %defaults, A => 2, B => 2 }, '-C with invalid value sets both B and A to default' ); test_loader( argv => ['--context=5'], expected_opts => { %defaults, A => 5, B => 5 }, '--context sets both B and A' ); test_loader( argv => ['--context'], expected_opts => { %defaults, A => 2, B => 2 }, '--context sets both B and A, with default' ); test_loader( argv => ['--context=0'], expected_opts => { %defaults, A => 0, B => 0 }, '--context sets both B and A, with zero overriding default' ); test_loader( argv => ['--context=-43'], expected_opts => { %defaults, A => 2, B => 2 }, '--context with invalid value sets both B and A to default' ); subtest 'ACK_PAGER' => sub { plan tests => 3; local $ENV{'ACK_PAGER'} = 't/test-pager --skip=2'; test_loader( argv => [], expected_opts => { %defaults, pager => 't/test-pager --skip=2' }, 'ACK_PAGER should set the default pager', ); test_loader( argv => ['--pager=t/test-pager'], expected_opts => { %defaults, pager => 't/test-pager' }, '--pager should override ACK_PAGER', ); test_loader( argv => ['--nopager'], expected_opts => { %defaults }, '--nopager should suppress ACK_PAGER', ); }; subtest 'ACK_PAGER_COLOR' => sub { plan tests => 6; local $ENV{'ACK_PAGER_COLOR'} = 't/test-pager --skip=2'; test_loader( argv => [], expected_opts => { %defaults, pager => 't/test-pager --skip=2' }, 'ACK_PAGER_COLOR should set the default pager', ); test_loader( argv => ['--pager=t/test-pager'], expected_opts => { %defaults, pager => 't/test-pager' }, '--pager should override ACK_PAGER_COLOR', ); test_loader( argv => ['--nopager'], expected_opts => { %defaults }, '--nopager should suppress ACK_PAGER_COLOR', ); local $ENV{'ACK_PAGER'} = 't/test-pager --skip=3'; test_loader( argv => [], expected_opts => { %defaults, pager => 't/test-pager --skip=2' }, 'ACK_PAGER_COLOR should override ACK_PAGER', ); test_loader( argv => ['--pager=t/test-pager'], expected_opts => { %defaults, pager => 't/test-pager' }, '--pager should override ACK_PAGER_COLOR and ACK_PAGER', ); test_loader( argv => ['--nopager'], expected_opts => { %defaults }, '--nopager should suppress ACK_PAGER_COLOR and ACK_PAGER', ); }; subtest 'PAGER' => sub { plan tests => 3; local $ENV{'PAGER'} = 't/test-pager'; test_loader( argv => [], expected_opts => { %defaults }, q{PAGER doesn't affect ack by default}, ); test_loader( argv => ['--pager'], expected_opts => { %defaults, pager => 't/test-pager' }, 'PAGER is used if --pager is specified with no argument', ); test_loader( argv => ['--pager=t/test-pager --skip=2'], expected_opts => { %defaults, pager => 't/test-pager --skip=2' }, 'PAGER is not used if --pager is specified with an argument', ); }; done_testing(); exit 0; sub test_loader { local $Test::Builder::Level = $Test::Builder::Level + 1; die 'Must pass key/value pairs, plus a message at the end' unless @_ % 2 == 1; my $msg = pop; my %opts = @_; return subtest subtest_name( $msg, \%opts ) => sub { plan tests => 3; my $env = delete $opts{env} // ''; my $argv = delete $opts{argv} // []; my $expected_opts = delete $opts{expected_opts}; is( scalar keys %opts, 0, 'All the keys are gone' ); my $got_opts; my $got_targets; do { local @ARGV = (); my @arg_sources = ( { name => 'ARGV', contents => $argv }, ); $got_opts = App::Ack::ConfigLoader::process_args( @arg_sources ); $got_targets = [ @ARGV ]; }; is_deeply( $got_opts, $expected_opts, 'Options match' ); is_empty_array( $got_targets, 'Got no targets' ); }; } ack-v3.5.0/t/internals/match-filter.t0000644000175100017510000000051614023027176016127 0ustar andyandy#!perl use strict; use warnings; use lib 't', 't/internals'; use FilterTest; use Test::More tests => 1; use App::Ack::Filter::Match; filter_test( [ match => '/^.akefile/' ], [ 't/swamp/Makefile', 't/swamp/Makefile.PL', 't/swamp/Rakefile', ], 'only files matching /^.akefile/ should be matched', ); ack-v3.5.0/t/internals/FilterTest.pm0000644000175100017510000000177714023027176016020 0ustar andyandypackage FilterTest; use strict; use warnings; use parent 'Exporter'; use App::Ack::File; use File::Next; use Util; use Test::More; our @EXPORT = qw(filter_test); sub swamp_files { my @swamp_files; my $files = File::Next::files( 't/swamp' ); while ( my $file = $files->() ) { push( @swamp_files, $file ); } return @swamp_files; } sub filter_test { local $Test::Builder::Level = $Test::Builder::Level + 1; my $filter_args = shift; my $expected_matches = shift; my $msg = shift or die 'Must pass a message to filter_test()'; return subtest "filter_test($msg)" => sub { my $filter = eval { App::Ack::Filter->create_filter(@{$filter_args}); }; ok($filter) or diag($@); my @matches = map { $_->name } grep { $filter->filter($_) } map { App::Ack::File->new($_) } swamp_files(); sets_match(\@matches, $expected_matches, $msg); }; } 1; ack-v3.5.0/t/internals/is-filter.t0000644000175100017510000000036214023027176015445 0ustar andyandy#!perl use strict; use warnings; use lib 't', 't/internals'; use FilterTest; use Test::More tests => 1; use App::Ack::Filter::Is; filter_test( [ is => 'Makefile' ], [ 't/swamp/Makefile' ], 'Only Makefile should be matched' ); ack-v3.5.0/t/internals/filter.t0000644000175100017510000000144414023027176015036 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 5; use App::Ack::Filter; my $filter; $filter = eval { App::Ack::Filter->create_filter('test'); }; ok( !$filter, 'Creating an unknown filter should fail' ); like( $@, qr/unknown filter/i, 'Got the expected error' ); App::Ack::Filter->register_filter(test => 'TestFilter'); $filter = eval { App::Ack::Filter->create_filter('test', qw/foo bar/); }; ok( $filter, 'Creating a registered filter should succeed' ) or diag($@); isa_ok( $filter, 'TestFilter', 'Creating a test filter should be a TestFilter' ); is_deeply( $filter, [qw/foo bar/], 'Extra arguments should get passed through to constructor' ); package TestFilter; use strict; use warnings; sub new { my ( $class, @args ) = @_; return bless \@args, $class; } 1; ack-v3.5.0/t/internals/firstlinematch-filter.t0000644000175100017510000000133114023027176020043 0ustar andyandy#!perl use strict; use warnings; use lib 't', 't/internals'; use FilterTest; use Test::More tests => 1; use App::Ack::Filter::FirstLineMatch; filter_test( [ firstlinematch => '/^#!.*perl/' ], [ 't/swamp/#emacs-workfile.pl#', 't/swamp/0', 't/swamp/Makefile.PL', 't/swamp/__pycache__/notes.pl', 't/swamp/options-crlf.pl', 't/swamp/options.pl', 't/swamp/options.pl.bak', 't/swamp/perl-test.t', 't/swamp/perl-without-extension', 't/swamp/perl.cgi', 't/swamp/perl.pl', 't/swamp/perl.pm', 't/swamp/blib/ignore.pm', 't/swamp/blib/ignore.pod', ], 'only files with "perl" in their first line should be matched' ); ack-v3.5.0/t/internals/ack-dump.t0000644000175100017510000000131314023027176015245 0ustar andyandy#!perl use strict; use warnings; use lib 't'; use Util; use Test::More tests => 5; use App::Ack::ConfigDefault; prep_environment(); DUMP: { my @expected = App::Ack::ConfigDefault::options_clean(); my @args = qw( --dump ); my @results = run_ack( @args ); is( $results[0], 'Defaults', 'header should be Defaults' ); splice @results, 0, 2; # remove header (2 lines) s/^\s*// for @results; sets_match( \@results, \@expected, __FILE__ ); my @perl = grep { /\bperl\b/ } @results; is( scalar @perl, 2, 'Two specs for Perl' ); my @ignore_dir = grep { /ignore-dir/ } @results; is( scalar @ignore_dir, 27, 'Twenty-seven specs for ignoring directories' ); } exit 0; ack-v3.5.0/t/internals/ack-create-ackrc.t0000644000175100017510000000147314023027176016633 0ustar andyandy#!perl use strict; use warnings; use lib 't'; use Test::More tests => 5; use Util; use App::Ack (); use App::Ack::ConfigDefault (); prep_environment(); my @commented = App::Ack::ConfigDefault::options(); my @uncommented = App::Ack::ConfigDefault::options_clean(); cmp_ok( scalar @commented, '>', scalar @uncommented, 'There are fewer lines in the uncommented options.' ); my @output = run_ack( 'ack', '--create-ackrc' ); ok(scalar(grep { $_ eq '--ignore-ack-defaults' } @output), '--ignore-ack-defaults should be present in output'); @output = grep { $_ ne '--ignore-ack-defaults' } @output; lists_match(\@output, \@commented, 'lines in output should match the default options'); my @versions = grep { /\Qack version $App::Ack::VERSION/ } @commented; is( scalar @versions, 1, 'Got exactly one version line' ); ack-v3.5.0/t/internals/default-filter.t0000644000175100017510000000631414023027176016461 0ustar andyandy#!perl use strict; use warnings; use lib 't', 't/internals'; use FilterTest; use Test::More tests => 1; use App::Ack::Filter::Default; use App::Ack::Filter; App::Ack::Filter->register_filter('default' => 'App::Ack::Filter::Default'); filter_test( [ 'default' ], [ 't/swamp/#emacs-workfile.pl#', 't/swamp/0', 't/swamp/constitution-100k.pl', 't/swamp/c-header.h', 't/swamp/c-source.c', 't/swamp/crystallography-weenies.f', 't/swamp/example.R', 't/swamp/file.bar', 't/swamp/file.foo', 't/swamp/fresh.css', 't/swamp/fresh.min.css', 't/swamp/fresh.css.min', 't/swamp/html.htm', 't/swamp/html.html', 't/swamp/incomplete-last-line.txt', 't/swamp/javascript.js', 't/swamp/lua-shebang-test', 't/swamp/Makefile', 't/swamp/Makefile.PL', 't/swamp/MasterPage.master', 't/swamp/minified.js.min', 't/swamp/minified.min.js', 't/swamp/not-an-#emacs-workfile#', 't/swamp/notaMakefile', 't/swamp/notaRakefile', 't/swamp/notes.md', 't/swamp/options-crlf.pl', 't/swamp/options.pl', 't/swamp/options.pl.bak', 't/swamp/perl-test.t', 't/swamp/perl-without-extension', 't/swamp/perl.cgi', 't/swamp/perl.handler.pod', 't/swamp/perl.pl', 't/swamp/perl.pm', 't/swamp/perl.pod', 't/swamp/pipe-stress-freaks.F', 't/swamp/Rakefile', 't/swamp/Sample.ascx', 't/swamp/Sample.asmx', 't/swamp/sample.asp', 't/swamp/sample.aspx', 't/swamp/sample.rake', 't/swamp/service.svc', 't/swamp/__pycache__/notes.pl', 't/swamp/blib/ignore.pm', 't/swamp/blib/ignore.pod', 't/swamp/groceries/fruit', 't/swamp/groceries/junk', 't/swamp/groceries/meat', 't/swamp/groceries/another_subdir/fruit', 't/swamp/groceries/another_subdir/junk', 't/swamp/groceries/another_subdir/meat', 't/swamp/groceries/another_subdir/CVS/fruit', 't/swamp/groceries/another_subdir/CVS/junk', 't/swamp/groceries/another_subdir/CVS/meat', 't/swamp/groceries/another_subdir/RCS/fruit', 't/swamp/groceries/another_subdir/RCS/junk', 't/swamp/groceries/another_subdir/RCS/meat', 't/swamp/groceries/dir.d/fruit', 't/swamp/groceries/dir.d/junk', 't/swamp/groceries/dir.d/meat', 't/swamp/groceries/dir.d/CVS/fruit', 't/swamp/groceries/dir.d/CVS/junk', 't/swamp/groceries/dir.d/CVS/meat', 't/swamp/groceries/dir.d/RCS/fruit', 't/swamp/groceries/dir.d/RCS/junk', 't/swamp/groceries/dir.d/RCS/meat', 't/swamp/groceries/CVS/fruit', 't/swamp/groceries/CVS/junk', 't/swamp/groceries/CVS/meat', 't/swamp/groceries/RCS/fruit', 't/swamp/groceries/RCS/junk', 't/swamp/groceries/RCS/meat', 't/swamp/groceries/subdir/fruit', 't/swamp/groceries/subdir/junk', 't/swamp/groceries/subdir/meat', 't/swamp/stuff.cmake', 't/swamp/CMakeLists.txt', 't/swamp/swamp/ignoreme.txt', ], 'only non-binary files should be matched' ); ack-v3.5.0/t/internals/config-finder.t0000644000175100017510000001642714023027176016272 0ustar andyandy#!perl use strict; use warnings; use lib 't'; use Util; use Cwd qw(realpath); use File::Spec; use File::Temp; use Test::Builder; use Test::More; use App::Ack::ConfigFinder; my $tmpdir = $ENV{'TMPDIR'}; my $home = $ENV{'HOME'}; for ( $tmpdir, $home ) { s{/$}{} if defined; } if ( $tmpdir && ($tmpdir =~ /^\Q$home/) ) { plan skip_all => "Your \$TMPDIR ($tmpdir) is set to a descendant directory of your home directory. This test is known to fail with such a setting. Please set your TMPDIR to something else to get this test to pass."; exit; } plan tests => 26; # Set HOME to a known value, so we get predictable results. local $ENV{HOME} = realpath('t/home'); # Clear the user's ACKRC so it doesn't throw out expect_ackrcs(). delete $ENV{'ACKRC'}; my $finder; my @global_filenames = create_globals(); my @global_files = map { +{ path => $_ } } @global_filenames; my @std_files = (@global_files, { path => File::Spec->catfile($ENV{'HOME'}, '.ackrc') }); my $wd = getcwd_clean(); my $tempdir = File::Temp->newdir; safe_chdir( $tempdir->dirname ); $finder = App::Ack::ConfigFinder->new; with_home( sub { expect_ackrcs( \@std_files, 'having no project file should return only the top level files' ); } ); no_home( sub { expect_ackrcs( \@global_files, 'only system-wide ackrc is returned if HOME is not defined with no project files' ); } ); safe_mkdir( 'foo' ); safe_mkdir( File::Spec->catdir('foo', 'bar') ); safe_mkdir( File::Spec->catdir('foo', 'bar', 'baz') ); safe_chdir( File::Spec->catdir('foo', 'bar', 'baz') ); touch_ackrc( '.ackrc' ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => File::Spec->rel2abs('.ackrc') }], 'a project file in the same directory should be detected' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => File::Spec->rel2abs('.ackrc') } ], 'a project file in the same directory should be detected' ); } ); unlink '.ackrc'; my $project_file = File::Spec->catfile($tempdir->dirname, 'foo', 'bar', '.ackrc'); touch_ackrc( $project_file ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => $project_file } ], 'a project file in the parent directory should be detected' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => $project_file } ], 'a project file in the parent directory should be detected' ); } ); unlink $project_file; $project_file = File::Spec->catfile($tempdir->dirname, 'foo', '.ackrc'); touch_ackrc( $project_file ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => $project_file } ], 'a project file in the grandparent directory should be detected' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => $project_file } ], 'a project file in the grandparent directory should be detected' ); } ); touch_ackrc( '.ackrc' ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => File::Spec->rel2abs('.ackrc') } ], 'a project file in the same directory should be detected, even with another one above it' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => File::Spec->rel2abs('.ackrc') } ], 'a project file in the same directory should be detected, even with another one above it' ); } ); unlink '.ackrc'; unlink $project_file; touch_ackrc( '_ackrc' ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => File::Spec->rel2abs('_ackrc') } ], 'a project file in the same directory should be detected' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => File::Spec->rel2abs('_ackrc') } ], 'a project file in the same directory should be detected' ); } ); unlink '_ackrc'; $project_file = File::Spec->catfile($tempdir->dirname, 'foo', '_ackrc'); touch_ackrc( $project_file ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => $project_file } ], 'a project file in the grandparent directory should be detected' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => $project_file } ], 'a project file in the grandparent directory should be detected' ); } ); touch_ackrc( '_ackrc' ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => File::Spec->rel2abs('_ackrc') } ], 'a project file in the same directory should be detected, even with another one above it' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => File::Spec->rel2abs('_ackrc') } ], 'a project file in the same directory should be detected, even with another one above it' ); } ); unlink $project_file; touch_ackrc( '.ackrc' ); do { my $finder_fn = sub { my $ok = eval { $finder->find_config_files }; my $err = $@; ok( !$ok, '.ackrc + _ackrc is error' ); like( $err, qr/contains both \.ackrc and _ackrc/, 'Got the expected error' ); }; with_home( $finder_fn ); no_home( $finder_fn ); unlink '.ackrc'; $project_file = File::Spec->catfile($tempdir->dirname, 'foo', '.ackrc'); touch_ackrc( $project_file ); with_home( sub { expect_ackrcs( [ @std_files, { project => 1, path => File::Spec->rel2abs('_ackrc') }], 'a lower-level _ackrc should be preferred to a higher-level .ackrc' ); } ); no_home( sub { expect_ackrcs( [ @global_files, { project => 1, path => File::Spec->rel2abs('_ackrc') } ], 'a lower-level _ackrc should be preferred to a higher-level .ackrc' ); } ); unlink '_ackrc'; }; do { my $test_home = File::Spec->catdir( $tempdir->dirname, 'foo' ); local $ENV{'HOME'} = $test_home; my $user_file = File::Spec->catfile( $test_home, '.ackrc'); touch_ackrc( $user_file ); expect_ackrcs( [ @global_files, { path => $user_file } ], q{Don't load the same ackrc file twice} ); unlink($user_file); }; do { safe_chdir( $tempdir->dirname ); local $ENV{'HOME'} = File::Spec->catfile($tempdir->dirname, 'foo'); my $user_file = File::Spec->catfile($ENV{'HOME'}, '.ackrc'); touch_ackrc( $user_file ); my $ackrc = create_tempfile(); local $ENV{'ACKRC'} = $ackrc->filename; expect_ackrcs( [ @global_files, { path => $ackrc->filename } ], q{ACKRC overrides user's HOME ackrc} ); unlink $ackrc->filename; expect_ackrcs( [ @global_files, { path => $user_file } ], q{ACKRC doesn't override if it doesn't exist} ); touch_ackrc( $ackrc->filename ); safe_chdir( 'foo' ); expect_ackrcs( [ @global_files, { path => $ackrc->filename}, { project => 1, path => $user_file } ], q{~/.ackrc should still be found as a project ackrc} ); unlink $ackrc->filename; }; safe_chdir( $wd ); clean_up_globals(); exit 0; sub with_home { my ( $fn ) = @_; $fn->(); return; } sub no_home { my ( $fn ) = @_; # We have to manually store the value of HOME because localized # delete isn't supported until Perl 5.12.0. my $home_saved = delete $ENV{HOME}; $fn->(); $ENV{HOME} = $home_saved; return; } sub expect_ackrcs { local $Test::Builder::Level = $Test::Builder::Level + 1; my $expected = shift; my $name = shift; my @got = $finder->find_config_files; my @expected = @{$expected}; foreach my $element (@got, @expected) { $element->{'path'} = realpath($element->{'path'}); } is_deeply( \@got, \@expected, $name ) or diag(explain(got=>\@got,expected=>\@expected)); return; } ack-v3.5.0/t/internals/file-iterator.t0000644000175100017510000000727014023027176016322 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; use File::Next; use lib 't'; use Util; prep_environment(); sub slurp { my $iter = shift; my @files; while ( defined ( my $file = $iter->() ) ) { push( @files, $file ); } return @files; } UNFILTERED: { my $iter = File::Next::files( { file_filter => undef, descend_filter => undef, }, 't/swamp' ); my @files = slurp( $iter ); sets_match( \@files, [qw( t/swamp/0 t/swamp/__pycache__/notes.pl t/swamp/blib/ignore.pm t/swamp/blib/ignore.pod t/swamp/constitution-100k.pl t/swamp/c-header.h t/swamp/c-source.c t/swamp/crystallography-weenies.f t/swamp/example.R t/swamp/favicon.ico t/swamp/file.bar t/swamp/file.foo t/swamp/fresh.css t/swamp/fresh.css.min t/swamp/fresh.min.css t/swamp/groceries/another_subdir/CVS/fruit t/swamp/groceries/another_subdir/CVS/junk t/swamp/groceries/another_subdir/CVS/meat t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/meat t/swamp/groceries/another_subdir/RCS/fruit t/swamp/groceries/another_subdir/RCS/junk t/swamp/groceries/another_subdir/RCS/meat t/swamp/groceries/dir.d/CVS/fruit t/swamp/groceries/dir.d/CVS/junk t/swamp/groceries/dir.d/CVS/meat t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/meat t/swamp/groceries/dir.d/RCS/fruit t/swamp/groceries/dir.d/RCS/junk t/swamp/groceries/dir.d/RCS/meat t/swamp/groceries/CVS/fruit t/swamp/groceries/CVS/junk t/swamp/groceries/CVS/meat t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/meat t/swamp/groceries/RCS/fruit t/swamp/groceries/RCS/junk t/swamp/groceries/RCS/meat t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/subdir/meat t/swamp/html.htm t/swamp/html.html t/swamp/incomplete-last-line.txt t/swamp/javascript.js t/swamp/lua-shebang-test t/swamp/Makefile t/swamp/Makefile.PL t/swamp/MasterPage.master t/swamp/minified.js.min t/swamp/minified.min.js t/swamp/moose-andy.jpg t/swamp/notaMakefile t/swamp/notaRakefile t/swamp/notes.md t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/options.pl.bak t/swamp/perl-test.t t/swamp/perl-without-extension t/swamp/perl.cgi t/swamp/perl.pl t/swamp/perl.handler.pod t/swamp/perl.pm t/swamp/perl.pod t/swamp/perl.tar.gz t/swamp/perltoot.jpg t/swamp/pipe-stress-freaks.F t/swamp/Rakefile t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.asp t/swamp/sample.aspx t/swamp/sample.rake t/swamp/service.svc t/swamp/solution8.tar t/swamp/stuff.cmake t/swamp/CMakeLists.txt t/swamp/swamp/ignoreme.txt ), 't/swamp/#emacs-workfile.pl#', 't/swamp/not-an-#emacs-workfile#', ], 'UNFILTERED' ); } done_testing(); ack-v3.5.0/t/internals/lowercase.t0000644000175100017510000000463614023027176015543 0ustar andyandy#!/usr/bin/perl use warnings; use strict; use 5.010; use Test::More tests => 2; use App::Ack; my $lc_list = <<'END'; ## no critic ( CodeLayout::RequireASCII ) select . from table select \S+ from table select [^\s]+ from table # Character specifications find a tab -> \x09 "foo" in hex -> \x66\x6f\x6f with lowercase digits "foo" in hex -> \x66\x6F\x6F with uppercase digits control sequences: ctrl-x=\cX # unicode sequences: \N{GRAVE ACCENT} unicode sequences: \N{U+263D} ladies and gentlemen, please welcome, ❤️! # Regex metacharacters keep stuff to the left -> \K non-word character -> \W non-space character -> \S non-digit character -> \D something something \X not vertical whitespace -> \V not horizontal whitespace -> \H linebreak -> \R # unicode regex metachars # https://www.regular-expressions.info/unicode.html named property -> \p{Word} same as \w not the named property -> \P{Word} same as \W single-character named property shorthand -> \pL is any letter negation of single-character named property shorthand -> \PL is not any letter # Not sure about \X big combination: \W\S\D\V\H\R but still lowercase # Zero-width assertions not a word boundary -> \B beginning of a string -> \A end of a string -> \Z end-of-match position of prior match -> \G # Captures named capture group and backref -> (?'NAME'pattern) \k'NAME' named capture group and backref -> (?pattern) \k # Weird combinations \A\B\S{14}\G\Dfoo\W*\S+\Z END my $uc_list = <<'END'; This is \\Here. foo[A-Z]+ [A-Z]*bar parens([A-Z]*) foo(?!lookahead)([A-Z]*) # Don't get confused by regex metacharacters. \WWhat now? dumb \DDonald lost in \SSpace lost in \\\\Diskland # Weird combinations \A\\\B\S{14}\G\\\D\\Dog\\\W*\\\\\S+\\\\\Z \\W//\\W//\\Larry//\\D//? END my @lc_list = _big_split($lc_list); if ( $] >= 5.012 ) { push( @lc_list, 'anything but \n -> \N' ); } my @uc_list = _big_split($uc_list); subtest 'Check lowercase' => sub { plan tests => scalar @lc_list; for my $lc ( @lc_list ) { my $re = qr/$lc/; ok( App::Ack::is_lowercase( $lc ), qq{"$lc" should be lowercase} ); } }; subtest 'Check uppercase' => sub { plan tests => scalar @uc_list; for my $uc ( @uc_list ) { my $re = qr/$uc/; ok( !App::Ack::is_lowercase( $uc ), qq{"$uc" should not be lowercase} ); } }; done_testing(); exit 0; sub _big_split { my $str = shift; return grep { /./ && !/^#/ } split( /\n/, $str ); } ack-v3.5.0/t/forbidden-options.t0000644000175100017510000001022214023027176015171 0ustar andyandy#!perl # XXX This test need to include not-forbidden-options, like --sort and --smart-case. use strict; use warnings; use Test::More tests => 2; use File::Spec (); use File::Temp (); use lib 't'; use Util; prep_environment(); # Global: # /tmp/x/etc/.ackrc # /tmp/x/swamp my $wd = getcwd_clean(); _test_project_ackrc(); _test_home_ackrc(); exit 0; # Test project directory # ackrc in /tmp/x/project/.ackrc sub _test_project_ackrc { local $Test::Builder::Level = $Test::Builder::Level + 1; return subtest subtest_name() => sub { plan tests => 3; my $base_obj = File::Temp->newdir; my $base = $base_obj->dirname; # /tmp/x/project my $projectdir = File::Spec->catdir( $base, 'project' ); safe_mkdir( $projectdir ); # /tmp/x/project/subdir my $projectsubdir = File::Spec->catdir( $projectdir, 'subdir' ); safe_mkdir( $projectsubdir ); # /tmp/x/project/subdir/foo.pl my $projectfile = File::Spec->catfile( $projectsubdir, 'foo.pl' ); write_file( $projectfile, '#!/usr/bin/perl' ); safe_chdir( $projectdir ); # All three of these options are illegal in a project .ackrc. for my $option ( qw( match output pager ) ) { subtest $option => sub { plan tests => 2; # /tmp/x/project/.ackrc _create_ackrc( $projectdir, "--$option=$option" ); # Explicitly pass --env or else the test will ignore .ackrc. my ( $stdout, $stderr ) = run_ack_with_stderr( '-f', '--env' ); is_empty_array( $stdout, 'No output with the errors' ); if ( $option eq 'pager' ) { first_line_like( $stderr, qr/\QOption --$option is forbidden in project .ackrc files/, "$option illegal" ); } else { first_line_like( $stderr, qr/\QOption --$option is forbidden in .ackrc files/, "$option illegal" ); } }; } # Go back to working directory so the temporary directories can get erased. safe_chdir( $wd ); }; } # Test home directory # ackrc in /tmp/x/home/.ackrc # search in /tmp/x/swamp sub _test_home_ackrc { local $Test::Builder::Level = $Test::Builder::Level + 1; return subtest subtest_name() => sub { plan tests => 3; my $base_obj = File::Temp->newdir; my $base = $base_obj->dirname; # /tmp/x/home my $homedir = File::Spec->catdir( $base, 'home' ); safe_mkdir( $homedir ); # /tmp/x/project my $projectdir = File::Spec->catdir( $base, 'project' ); safe_mkdir( $projectdir ); # /tmp/x/project/foo.pl my $projectfile = File::Spec->catfile( $projectdir, 'foo.pl' ); write_file( $projectfile, '#!/usr/bin/perl' ); safe_chdir( $projectdir ); # --match and --output are illegal in a home .ackrc, but --pager is ok. for my $option ( qw( match output pager ) ) { subtest $option => sub { plan tests => 2; # /tmp/x/home/.ackrc _create_ackrc( $homedir, "--$option=$option" ); local $ENV{HOME} = $homedir; # Explicitly pass --env or else the test will ignore .ackrc. my ( $stdout, $stderr ) = run_ack_with_stderr( '-f', '--env' ); if ( $option eq 'pager' ) { is_deeply( $stdout, [ 'foo.pl' ], 'Found foo.pl OK' ); is_empty_array( $stderr, '--pager is OK' ); } else { is_empty_array( $stdout, 'No output with the errors' ); first_line_like( $stderr, qr/\QOption --$option is forbidden in .ackrc files/, "$option illegal" ); } }; } # Go back to working directory so the temporary directories can get erased. safe_chdir( $wd ); }; } sub _create_ackrc { my $dir = shift; my $option = shift; my $ackrc = File::Spec->catfile( $dir, '.ackrc' ); write_file( $ackrc, join( "\n", '--sort-files', $option, '--smart-case', '' ) ); return $ackrc; } ack-v3.5.0/t/ack-type-del.t0000644000175100017510000000305114023027176014025 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 12; use lib 't'; use Util; prep_environment(); my ( $stdout, $stderr ); my $help_types_output; # sanity check ( $stdout, $stderr ) = run_ack_with_stderr('-t', 'perl', '-f', 't/swamp'); is( scalar(@{$stdout}), 12, 'Found initial 11 files' ); is_empty_array( $stderr, 'Nothing in stderr' ); ( $stdout, $stderr ) = run_ack_with_stderr('--type-del=perl', '--type-del=perltest', '-t', 'perl', '-f', 't/swamp'); is_empty_array( $stdout, 'Nothing in stdout' ); first_line_like( $stderr, qr/Unknown type 'perl'/ ); ( $stdout, $stderr ) = run_ack_with_stderr('--type-del=perl', '--type-del=perltest', '--type-add=perl:ext:pm', '-t', 'perl', '-f', 't/swamp'); is( scalar(@{$stdout}), 1, 'Got one output line' ); is_empty_array( $stderr, 'Nothing in stderr' ); # more sanity checking $help_types_output = run_ack( '--help-types' ); like( $help_types_output, qr/\Qperl/ ); $help_types_output = run_ack( '--type-del=perl', '--type-del=perltest', '--help-types' ); unlike( $help_types_output, qr/\Qperl/ ); DUMP: { my @dump_output = run_ack( '--type-del=perl', '--type-del=perltest', '--dump' ); # discard everything up to the ARGV section while ( @dump_output && $dump_output[0] ne 'ARGV' ) { shift @dump_output; } shift @dump_output; # discard ARGV shift @dump_output; # discard header foreach my $line (@dump_output) { $line =~ s/^\s+|\s+$//g; } lists_match( \@dump_output, ['--type-del=perl', '--type-del=perltest'], '--type-del should show up in --dump output' ); } ack-v3.5.0/t/ack-m.t0000644000175100017510000000310414023027176012535 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 2; use lib 't'; use Util; prep_environment(); subtest 'Basic -m' => sub { plan tests => 2; my @text = sort map { untaint($_) } glob( 't/text/[bc]*.txt' ); my $bill_ = reslash( 't/text/bill-of-rights.txt' ); my $const = reslash( 't/text/constitution.txt' ); my @expected = split( /\n/, <<"HERE" ); $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of $bill_:5:speech, or of the press; or the right of the people peaceably to assemble, $bill_:6:and to petition the Government for a redress of grievances. $const:3:We the People of the United States, in Order to form a more perfect $const:4:Union, establish Justice, insure domestic Tranquility, provide for the $const:5:common defense, promote the general Welfare, and secure the Blessings HERE ack_lists_match( [ '-m', 3, '-w', 'the', @text ], \@expected, 'Should show only 3 lines per file' ); @expected = split( /\n/, <<"HERE" ); $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of HERE ack_lists_match( [ '-1', '-w', 'the', @text ], \@expected, 'We should only get one line back for the entire run, not just per file.' ); }; subtest '-m with -L' => sub { plan tests => 2; my @files = reslash( 't/text' ); my @args = ( '-m', 3, '-l', '--sort-files', 'the' ); my @results = run_ack( @args, @files ); my @expected = map { reslash( "t/text/$_" ) } qw( amontillado.txt bill-of-rights.txt constitution.txt ); is_deeply(\@results, \@expected); }; done_testing(); exit 0; ack-v3.5.0/t/filetype-detection.t0000644000175100017510000000161614023027176015350 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 3; use lib 't'; use Util; prep_environment(); subtest 'Lua shebang' => sub { plan tests => 1; ack_sets_match( [qw( -t lua -f t/swamp )], [ 't/swamp/lua-shebang-test' ], 'Lua files should be detected by shebang' ); }; subtest 'R extensions' => sub { plan tests => 2; my @expected = qw( t/swamp/example.R ); my @args = qw( -t rr -f ); my @results = run_ack( @args ); sets_match( \@results, \@expected, __FILE__ ); }; subtest 'ASP.NET' => sub { my @expected = qw( t/swamp/MasterPage.master t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.aspx t/swamp/service.svc ); my @args = qw( -t aspx -f ); my @results = run_ack(@args); sets_match( \@results, \@expected, __FILE__ ); }; done_testing(); exit 0; ack-v3.5.0/t/from-stdin.t0000644000175100017510000000246214023027176013635 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 3; use lib 't'; use Util; prep_environment(); PIPE_INTO_ACK: { my @expected = line_split( <<'END' ); Of 'Never -- nevermore.' She shall press, ah, nevermore! Shall be lifted--nevermore! END my $file = 't/text/raven.txt'; my @args = qw( nevermore ); my @results = pipe_into_ack( $file, @args ); is_deeply( \@results, \@expected, 'Piping a file' ); } PIPE_INTO_DASH_I: { my @expected = line_split( <<'END' ); Quoth the Raven, "Nevermore." With such name as "Nevermore." Then the bird said, "Nevermore." Of 'Never -- nevermore.' Meant in croaking "Nevermore." She shall press, ah, nevermore! Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Shall be lifted--nevermore! END my $file = 't/text/raven.txt'; my @args = qw( nevermore -i ); my @results = pipe_into_ack( $file, @args ); is_deeply( \@results, \@expected, 'Piping a file with -i' ); } PIPE_INTO_DASH_C: { my $file = 't/text/raven.txt'; my @args = qw( nevermore -i -c ); my @results = pipe_into_ack( $file, @args ); is_deeply( \@results, [ 11 ], 'Piping into ack --count should return one line of results' ); } exit 0; ack-v3.5.0/t/text/0000755000175100017510000000000014023040526012340 5ustar andyandyack-v3.5.0/t/text/numbered-text.txt0000644000175100017510000000050014023027176015665 0ustar andyandyThis is line 01 This is line 02 This is line 03 This is line 04 This is line 05 This is line 06 This is line 07 This is line 08 This is line 09 This is line 10 This is line 11 This is line 12 This is line 13 This is line 14 This is line 15 This is line 16 This is line 17 This is line 18 This is line 19 This is line 20 ack-v3.5.0/t/text/bill-of-rights.txt0000644000175100017510000000541214023027176015733 0ustar andyandy# Amendment I Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the Government for a redress of grievances. # Amendment II A well regulated Militia, being necessary to the security of a free State, the right of the people to keep and bear Arms, shall not be infringed. # Amendment III No Soldier shall, in time of peace be quartered in any house, without the consent of the Owner, nor in time of war, but in a manner to be prescribed by law. # Amendment IV The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no Warrants shall issue, but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. # Amendment V No person shall be held to answer for a capital, or otherwise infamous crime, unless on a presentment or indictment of a Grand Jury, except in cases arising in the land or naval forces, or in the Militia, when in actual service in time of War or public danger; nor shall any person be subject for the same offence to be twice put in jeopardy of life or limb; nor shall be compelled in any criminal case to be a witness against himself, nor be deprived of life, liberty, or property, without due process of law; nor shall private property be taken for public use, without just compensation. # Amendment VI In all criminal prosecutions, the accused shall enjoy the right to a speedy and public trial, by an impartial jury of the State and district wherein the crime shall have been committed, which district shall have been previously ascertained by law, and to be informed of the nature and cause of the accusation; to be confronted with the witnesses against him; to have compulsory process for obtaining witnesses in his favor, and to have the Assistance of Counsel for his defence. # Amendment VII In Suits at common law, where the value in controversy shall exceed twenty dollars, the right of trial by jury shall be preserved, and no fact tried by a jury, shall be otherwise re-examined in any Court of the United States, than according to the rules of the common law. # Amendment VIII Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted. # Amendment IX The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people. # Amendment X The powers not delegated to the United States by the Constitution, nor prohibited by it to the States, are reserved to the States respectively, or to the people. ack-v3.5.0/t/text/number.txt0000644000175100017510000000000614023027176014373 0ustar andyandy86700 ack-v3.5.0/t/text/gettysburg.txt0000644000175100017510000000270414023027176015311 0ustar andyandyFour score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate -- we can not consecrate -- we can not hallow -- this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us -- that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion -- that we here highly resolve that these dead shall not have died in vain -- that this nation, under God, shall have a new birth of freedom -- and that government of the people, by the people, for the people, shall not perish from the earth. ack-v3.5.0/t/text/raven.txt0000644000175100017510000001431714023027176014230 0ustar andyandyOnce upon a midnight dreary, while I pondered, weak and weary, Over many a quaint and curious volume of forgotten lore, -- While I nodded, nearly napping, suddenly there came a tapping, As of some one gently rapping, rapping at my chamber door. "'Tis some visitor," I muttered, "tapping at my chamber door; Only this and nothing more." Ah, distinctly I remember it was in the bleak December And each separate dying ember wrought its ghost upon the floor. Eagerly I wished the morrow; -- vainly I had sought to borrow From my books surcease of sorrow -- sorrow for the lost Lenore, For the rare and radiant maiden whom the angels name Lenore: Nameless here for evermore. And the silken sad uncertain rustling of each purple curtain Thrilled me -- filled me with fantastic terrors never felt before; So that now, to still the beating of my heart, I stood repeating "'T is some visitor entreating entrance at my chamber door, Some late visitor entreating entrance at my chamber door: This it is and nothing more." Presently my soul grew stronger; hesitating then no longer, "Sir," said I, "or Madam, truly your forgiveness I implore; But the fact is I was napping, and so gently you came rapping, And so faintly you came tapping, tapping at my chamber door, That I scarce was sure I heard you" -- here I opened wide the door: -- Darkness there and nothing more. Deep into that darkness peering, long I stood there wondering, fearing, Doubting, dreaming dreams no mortals ever dared to dream before; But the silence was unbroken, and the stillness gave no token, And the only word there spoken was the whispered word, "Lenore?" This I whispered, and an echo murmured back the word, "Lenore:" Merely this and nothing more. Back into the chamber turning, all my soul within me burning, Soon again I heard a tapping somewhat louder than before. "Surely," said I, "surely that is something at my window lattice; Let me see, then, what thereat is, and this mystery explore; Let my heart be still a moment and this mystery explore: 'T is the wind and nothing more." Open here I flung the shutter, when, with many a flirt and flutter, In there stepped a stately Raven of the saintly days of yore. Not the least obeisance made he; not a minute stopped or stayed he; But, with mien of lord or lady, perched above my chamber door, Perched upon a bust of Pallas just above my chamber door: Perched, and sat, and nothing more. Then this ebony bird beguiling my sad fancy into smiling By the grave and stern decorum of the countenance it wore, "Though thy crest be shorn and shaven, thou," I said, "art sure no craven, Ghastly grim and ancient Raven wandering from the Nightly shore: Tell me what thy lordly name is on the Night's Plutonian shore!" Quoth the Raven, "Nevermore." Much I marvelled this ungainly fowl to hear discourse so plainly, Though its answer little meaning -- little relevancy bore; For we cannot help agreeing that no living human being Ever yet was blessed with seeing bird above his chamber door, Bird or beast upon the sculptured bust above his chamber door, With such name as "Nevermore." But the Raven, sitting lonely on the placid bust, spoke only That one word, as if his soul in that one word he did outpour. Nothing further then he uttered, not a feather then he fluttered, Till I scarcely more than muttered, -- "Other friends have flown before; On the morrow he will leave me, as my Hopes have flown before." Then the bird said, "Nevermore." Startled at the stillness broken by reply so aptly spoken, "Doubtless," said I, "what it utters is its only stock and store, Caught from some unhappy master whom unmerciful Disaster Followed fast and followed faster till his songs one burden bore: Till the dirges of his Hope that melancholy burden bore Of 'Never -- nevermore.' But the Raven still beguiling all my fancy into smiling, Straight I wheeled a cushioned seat in front of bird and bust and door; Then, upon the velvet sinking, I betook myself to linking Fancy unto fancy, thinking what this ominous bird of yore, What this grim, ungainly, ghastly, gaunt, and ominous bird of yore Meant in croaking "Nevermore." This I sat engaged in guessing, but no syllable expressing To the fowl whose fiery eyes now burned into my bosom's core; This and more I sat divining, with my head at ease reclining On the cushion's velvet lining that the lamplight gloated o'er, But whose velvet violet lining with the lamp-light gloating o'er She shall press, ah, nevermore! Then, methought, the air grew denser, perfumed from an unseen censer Swung by seraphim whose foot-falls tinkled on the tufted floor. "Wretch," I cried, "thy God hath lent thee -- by these angels he hath sent thee Respite-respite and nepenthe from thy memories of Lenore!" Quaff, oh quaff this kind nepenthe, and forget this lost Lenore." Quoth the Raven, "Nevermore." "Prophet!" said I, "thing of evil! prophet still, if bird or devil! Whether Tempter sent, or whether tempest tossed thee here ashore, Desolate yet all undaunted, on this desert land enchanted On this home by Horror haunted -- tell me truly, I implore: Is there -- is there balm in Gilead? -- tell me -- tell me, I implore!" Quoth the Raven, "Nevermore." "Prophet!" said I, "thing of evil -- prophet still, if bird or devil! By that Heaven that bends above us, by that God we both adore, Tell this soul with sorrow laden if, within the distant Aidenn, It shall clasp a sainted maiden whom the angels name Lenore: Clasp a rare and radiant maiden whom the angels name Lenore!" Quoth the Raven, "Nevermore." "Be that word our sign of parting, bird or fiend!" I shrieked, upstarting: "Get thee back into the tempest and the Night's Plutonian shore! Leave no black plume as a token of that lie thy soul hath spoken! Leave my loneliness unbroken! quit the bust above my door! Take thy beak from out my heart, and take thy form from off my door!" Quoth the Raven, "Nevermore." And the Raven, never flitting, still is sitting, still is sitting On the pallid bust of Pallas just above my chamber door; And his eyes have all the seeming of a demon's that is dreaming, And the lamp-light o'er him streaming throws his shadow on the floor: And my soul from out that shadow that lies floating on the floor Shall be lifted--nevermore! ack-v3.5.0/t/text/ozymandias.txt0000644000175100017510000000116314023027176015266 0ustar andyandyI met a traveller from an antique land Who said: Two vast and trunkless legs of stone Stand in the desert... Near them, on the sand, Half sunk, a shattered visage lies, whose frown, And wrinkled lip, and sneer of cold command, Tell that its sculptor well those passions read Which yet survive, stamped on these lifeless things, The hand that mocked them, and the heart that fed: And on the pedestal these words appear: 'My name is Ozymandias, king of kings: Look on my works, ye Mighty, and despair!' Nothing beside remains. Round the decay Of that colossal wreck, boundless and bare The lone and level sands stretch far away. ack-v3.5.0/t/text/amontillado.txt0000644000175100017510000003120314023027176015411 0ustar andyandy# The Cask of Amontillado, by Edgar Allen Poe The thousand injuries of Fortunato I had borne as I best could; but when he ventured upon insult, I vowed revenge. You, who so well know the nature of my soul, will not suppose, however, that I gave utterance to a threat. At length I would be avenged; this was a point definitively settled--but the very definitiveness with which it was resolved, precluded the idea of risk. I must not only punish, but punish with impunity. A wrong is unredressed when retribution overtakes its redresser. It is equally unredressed when the avenger fails to make himself felt as such to him who has done the wrong. It must be understood, that neither by word nor deed had I given Fortunato cause to doubt my good will. I continued, as was my wont, to smile in his face, and he did not perceive that my smile now was at the thought of his immolation. He had a weak point--this Fortunato--although in other regards he was a man to be respected and even feared. He prided himself on his connoisseurship in wine. Few Italians have the true virtuoso spirit. For the most part their enthusiasm is adopted to suit the time and opportunity--to practise imposture upon the British and Austrian millionaires. In painting and gemmary Fortunato, like his countrymen, was a quack--but in the matter of old wines he was sincere. In this respect I did not differ from him materially: I was skilful in the Italian vintages myself, and bought largely whenever I could. It was about dusk, one evening during the supreme madness of the carnival season, that I encountered my friend. He accosted me with excessive warmth, for he had been drinking much. The man wore motley. He had on a tight-fitting parti-striped dress, and his head was surmounted by the conical cap and bells. I was so pleased to see him, that I thought I should never have done wringing his hand. I said to him--"My dear Fortunato, you are luckily met. How remarkably well you are looking to-day! But I have received a pipe of what passes for Amontillado, and I have my doubts." "How?" said he. "Amontillado? A pipe! Impossible! And in the middle of the carnival!" "I have my doubts," I replied; "and I was silly enough to pay the full Amontillado price without consulting you in the matter. You were not to be found, and I was fearful of losing a bargain." "Amontillado!" "I have my doubts." "Amontillado!" "And I must satisfy them." "Amontillado!" "As you are engaged, I am on my way to Luchesi. If any one has a critical turn, it is he. He will tell me--" "Luchesi cannot tell Amontillado from Sherry." "And yet some fools will have it that his taste is a match for your own." "Come, let us go." "Whither?" "To your vaults." "My friend, no; I will not impose upon your good nature. I perceive you have an engagement. Luchesi--" "I have no engagement;--come." "My friend, no. It is not the engagement, but the severe cold with which I perceive you are afflicted. The vaults are insufferably damp. They are encrusted with nitre." "Let us go, nevertheless. The cold is merely nothing. Amontillado! You have been imposed upon. And as for Luchesi, he cannot distinguish Sherry from Amontillado." Thus speaking, Fortunato possessed himself of my arm. Putting on a mask of black silk, and drawing a roquelaire closely about my person, I suffered him to hurry me to my palazzo. There were no attendants at home; they had absconded to make merry in honor of the time. I had told them that I should not return until the morning, and had given them explicit orders not to stir from the house. These orders were sufficient, I well knew, to insure their immediate disappearance, one and all, as soon as my back was turned. I took from their sconces two flambeaux, and giving one to Fortunato, bowed him through several suites of rooms to the archway that led into the vaults. I passed down a long and winding staircase, requesting him to be cautious as he followed. We came at length to the foot of the descent, and stood together on the damp ground of the catacombs of the Montresors. The gait of my friend was unsteady, and the bells upon his cap jingled as he strode. "The pipe," said he. "It is farther on," said I; "but observe the white web-work which gleams from these cavern walls." He turned towards me, and looked into my eyes with two filmy orbs that distilled the rheum of intoxication. "Nitre?" he asked, at length. "Nitre," I replied. "How long have you had that cough?" "Ugh! ugh! ugh!--ugh! ugh! ugh!--ugh! ugh! ugh!--ugh! ugh! ugh!--ugh! ugh! ugh!" My poor friend found it impossible to reply for many minutes. "It is nothing," he said, at last. "Come," I said, with decision, "we will go back; your health is precious. You are rich, respected, admired, beloved; you are happy, as once I was. You are a man to be missed. For me it is no matter. We will go back; you will be ill, and I cannot be responsible. Besides, there is Luchesi--" "Enough," he said; "the cough is a mere nothing; it will not kill me. I shall not die of a cough." "True--true," I replied; "and, indeed, I had no intention of alarming you unnecessarily--but you should use all proper caution. A draught of this Medoc will defend us from the damps." Here I knocked off the neck of a bottle which I drew from a long row of its fellows that lay upon the mould. "Drink," I said, presenting him the wine. He raised it to his lips with a leer. He paused and nodded to me familiarly, while his bells jingled. "I drink," he said, "to the buried that repose around us." "And I to your long life." He again took my arm, and we proceeded. "These vaults," he said, "are extensive." "The Montresors," I replied, "were a great and numerous family." "I forget your arms." "A huge human foot d'or, in a field azure; the foot crushes a serpent rampant whose fangs are imbedded in the heel." "And the motto?" "Nemo me impune lacessit." "Good!" he said. The wine sparkled in his eyes and the bells jingled. My own fancy grew warm with the Medoc. We had passed through walls of piled bones, with casks and puncheons intermingling, into the inmost recesses of the catacombs. I paused again, and this time I made bold to seize Fortunato by an arm above the elbow. "The nitre!" I said; "see, it increases. It hangs like moss upon the vaults. We are below the river's bed. The drops of moisture trickle among the bones. Come, we will go back ere it is too late. Your cough--" "It is nothing," he said; "let us go on. But first, another draught of the Medoc." I broke and reached him a flaçon of De Grâve. He emptied it at a breath. His eyes flashed with a fierce light. He laughed and threw the bottle upwards with a gesticulation I did not understand. I looked at him in surprise. He repeated the movement--a grotesque one. "You do not comprehend?" he said. "Not I," I replied. "Then you are not of the brotherhood." "How?" "You are not of the masons." "Yes, yes," I said, "yes, yes." "You? Impossible! A mason?" "A mason," I replied. "A sign," he said. "It is this," I answered, producing a trowel from beneath the folds of my roquelaire. "You jest," he exclaimed, recoiling a few paces. "But let us proceed to the Amontillado." "Be it so," I said, replacing the tool beneath the cloak, and again offering him my arm. He leaned upon it heavily. We continued our route in search of the Amontillado. We passed through a range of low arches, descended, passed on, and descending again, arrived at a deep crypt, in which the foulness of the air caused our flambeaux rather to glow than flame. At the most remote end of the crypt there appeared another less spacious. Its walls had been lined with human remains, piled to the vault overhead, in the fashion of the great catacombs of Paris. Three sides of this interior crypt were still ornamented in this manner. From the fourth side the bones had been thrown down, and lay promiscuously upon the earth, forming at one point a mound of some size. Within the wall thus exposed by the displacing of the bones, we perceived a still interior recess, in depth about four feet, in width three, in height six or seven. It seemed to have been constructed for no especial use within itself, but formed merely the interval between two of the colossal supports of the roof of the catacombs, and was backed by one of their circumscribing walls of solid granite. It was in vain that Fortunato, uplifting his dull torch, endeavored to pry into the depth of the recess. Its termination the feeble light did not enable us to see. "Proceed," I said; "herein is the Amontillado. As for Luchesi--" "He is an ignoramus," interrupted my friend, as he stepped unsteadily forward, while I followed immediately at his heels. In an instant he had reached the extremity of the niche, and finding his progress arrested by the rock, stood stupidly bewildered. A moment more and I had fettered him to the granite. In its surface were two iron staples, distant from each other about two feet, horizontally. From one of these depended a short chain, from the other a padlock. Throwing the links about his waist, it was but the work of a few seconds to secure it. He was too much astounded to resist. Withdrawing the key I stepped back from the recess. "Pass your hand," I said, "over the wall; you cannot help feeling the nitre. Indeed it is very damp. Once more let me implore you to return. No? Then I must positively leave you. But I must first render you all the little attentions in my power." "The Amontillado!" ejaculated my friend, not yet recovered from his astonishment. "True," I replied; "the Amontillado." As I said these words I busied myself among the pile of bones of which I have before spoken. Throwing them aside, I soon uncovered a quantity of building stone and mortar. With these materials and with the aid of my trowel, I began vigorously to wall up the entrance of the niche. I had scarcely laid the first tier of the masonry when I discovered that the intoxication of Fortunato had in a great measure worn off. The earliest indication I had of this was a low moaning cry from the depth of the recess. It was not the cry of a drunken man. There was then a long and obstinate silence. I laid the second tier, and the third, and the fourth; and then I heard the furious vibrations of the chain. The noise lasted for several minutes, during which, that I might hearken to it with the more satisfaction, I ceased my labors and sat down upon the bones. When at last the clanking subsided, I resumed the trowel, and finished without interruption the fifth, the sixth, and the seventh tier. The wall was now nearly upon a level with my breast. I again paused, and holding the flambeaux over the mason-work, threw a few feeble rays upon the figure within. A succession of loud and shrill screams, bursting suddenly from the throat of the chained form, seemed to thrust me violently back. For a brief moment I hesitated--I trembled. Unsheathing my rapier, I began to grope with it about the recess: but the thought of an instant reassured me. I placed my hand upon the solid fabric of the catacombs, and felt satisfied. I reapproached the wall. I replied to the yells of him who clamored. I re-echoed--I aided--I surpassed them in volume and in strength. I did this, and the clamorer grew still. It was now midnight, and my task was drawing to a close. I had completed the eighth, the ninth, and the tenth tier. I had finished a portion of the last and the eleventh; there remained but a single stone to be fitted and plastered in. I struggled with its weight; I placed it partially in its destined position. But now there came from out the niche a low laugh that erected the hairs upon my head. It was succeeded by a sad voice, which I had difficulty in recognising as that of the noble Fortunato. The voice said-- "Ha! ha! ha!--he! he!--a very good joke indeed--an excellent jest. We will have many a rich laugh about it at the palazzo--he! he! he!--over our wine--he! he! he!" "The Amontillado!" I said. "He! he! he!--he! he! he!--yes, the Amontillado. But is it not getting late? Will not they be awaiting us at the palazzo, the Lady Fortunato and the rest? Let us be gone." "Yes,"I said, "let us be gone." "For the love of God, Montresor!" "Yes," I said, "for the love of God!" But to these words I hearkened in vain for a reply. I grew impatient. I called aloud-- "Fortunato!" No answer. I called again-- "Fortunato!" No answer still. I thrust a torch through the remaining aperture and let it fall within. There came forth in return only a jingling of the bells. My heart grew sick--on account of the dampness of the catacombs. I hastened to make an end of my labor. I forced the last stone into its position; I plastered it up. Against the new masonry I re-erected the old rampart of bones. For the half of a century no mortal has disturbed them. In pace requiescat! ack-v3.5.0/t/text/constitution.txt0000644000175100017510000006216614023027176015664 0ustar andyandy# Preamble We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America. # Article I ## Section 1 All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives. ## Section 2 The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment. ## Section 3 The Senate of the United States shall be composed of two Senators from each State, chosen by the Legislature thereof, for six Years; and each Senator shall have one Vote. Immediately after they shall be assembled in Consequence of the first Election, they shall be divided as equally as may be into three Classes. The Seats of the Senators of the first Class shall be vacated at the Expiration of the second Year, of the second Class at the Expiration of the fourth Year, and of the third Class at the Expiration of the sixth Year, so that one third may be chosen every second Year; and if Vacancies happen by Resignation, or otherwise, during the Recess of the Legislature of any State, the Executive thereof may make temporary Appointments until the next Meeting of the Legislature, which shall then fill such Vacancies. No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen. The Vice President of the United States shall be President of the Senate, but shall have no Vote, unless they be equally divided. The Senate shall chuse their other Officers, and also a President pro tempore, in the Absence of the Vice President, or when he shall exercise the Office of President of the United States. The Senate shall have the sole Power to try all Impeachments. When sitting for that Purpose, they shall be on Oath or Affirmation. When the President of the United States is tried, the Chief Justice shall preside: And no Person shall be convicted without the Concurrence of two thirds of the Members present. Judgment in Cases of Impeachment shall not extend further than to removal from Office, and disqualification to hold and enjoy any Office of honor, Trust or Profit under the United States: but the Party convicted shall nevertheless be liable and subject to Indictment, Trial, Judgment and Punishment, according to Law. ## Section 4 The Times, Places and Manner of holding Elections for Senators and Representatives, shall be prescribed in each State by the Legislature thereof; but the Congress may at any time by Law make or alter such Regulations, except as to the Places of chusing Senators. The Congress shall assemble at least once in every Year, and such Meeting shall be on the first Monday in December, unless they shall by Law appoint a different Day. ## Section 5 Each House shall be the Judge of the Elections, Returns and Qualifications of its own Members, and a Majority of each shall constitute a Quorum to do Business; but a smaller Number may adjourn from day to day, and may be authorized to compel the Attendance of absent Members, in such Manner, and under such Penalties as each House may provide. Each House may determine the Rules of its Proceedings, punish its Members for disorderly Behaviour, and, with the Concurrence of two thirds, expel a Member. Each House shall keep a Journal of its Proceedings, and from time to time publish the same, excepting such Parts as may in their Judgment require Secrecy; and the Yeas and Nays of the Members of either House on any question shall, at the Desire of one fifth of those Present, be entered on the Journal. Neither House, during the Session of Congress, shall, without the Consent of the other, adjourn for more than three days, nor to any other Place than that in which the two Houses shall be sitting. ## Section 6 The Senators and Representatives shall receive a Compensation for their Services, to be ascertained by Law, and paid out of the Treasury of the United States. They shall in all Cases, except Treason, Felony and Breach of the Peace, be privileged from Arrest during their Attendance at the Session of their respective Houses, and in going to and returning from the same; and for any Speech or Debate in either House, they shall not be questioned in any other Place. No Senator or Representative shall, during the Time for which he was elected, be appointed to any civil Office under the Authority of the United States, which shall have been created, or the Emoluments whereof shall have been encreased during such time; and no Person holding any Office under the United States, shall be a Member of either House during his Continuance in Office. ## Section 7 All Bills for raising Revenue shall originate in the House of Representatives; but the Senate may propose or concur with Amendments as on other Bills. Every Bill which shall have passed the House of Representatives and the Senate, shall, before it become a Law, be presented to the President of the United States: If he approve he shall sign it, but if not he shall return it, with his Objections to that House in which it shall have originated, who shall enter the Objections at large on their Journal, and proceed to reconsider it. If after such Reconsideration two thirds of that House shall agree to pass the Bill, it shall be sent, together with the Objections, to the other House, by which it shall likewise be reconsidered, and if approved by two thirds of that House, it shall become a Law. But in all such Cases the Votes of both Houses shall be determined by Yeas and Nays, and the Names of the Persons voting for and against the Bill shall be entered on the Journal of each House respectively. If any Bill shall not be returned by the President within ten Days (Sundays excepted) after it shall have been presented to him, the Same shall be a Law, in like Manner as if he had signed it, unless the Congress by their Adjournment prevent its Return, in which Case it shall not be a Law. Every Order, Resolution, or Vote to which the Concurrence of the Senate and House of Representatives may be necessary (except on a question of Adjournment) shall be presented to the President of the United States; and before the Same shall take Effect, shall be approved by him, or being disapproved by him, shall be repassed by two thirds of the Senate and House of Representatives, according to the Rules and Limitations prescribed in the Case of a Bill. ## Section 8 The Congress shall have Power To lay and collect Taxes, Duties, Imposts and Excises, to pay the Debts and provide for the common Defence and general Welfare of the United States; but all Duties, Imposts and Excises shall be uniform throughout the United States; To borrow Money on the credit of the United States; To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes; To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States; To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures; To provide for the Punishment of counterfeiting the Securities and current Coin of the United States; To establish Post Offices and post Roads; To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries; To constitute Tribunals inferior to the supreme Court; To define and punish Piracies and Felonies committed on the high Seas, and Offences against the Law of Nations; To declare War, grant Letters of Marque and Reprisal, and make Rules concerning Captures on Land and Water; To raise and support Armies, but no Appropriation of Money to that Use shall be for a longer Term than two Years; To provide and maintain a Navy; To make Rules for the Government and Regulation of the land and naval Forces; To provide for calling forth the Militia to execute the Laws of the Union, suppress Insurrections and repel Invasions; To provide for organizing, arming, and disciplining, the Militia, and for governing such Part of them as may be employed in the Service of the United States, reserving to the States respectively, the Appointment of the Officers, and the Authority of training the Militia according to the discipline prescribed by Congress; To exercise exclusive Legislation in all Cases whatsoever, over such District (not exceeding ten Miles square) as may, by Cession of particular States, and the Acceptance of Congress, become the Seat of the Government of the United States, and to exercise like Authority over all Places purchased by the Consent of the Legislature of the State in which the Same shall be, for the Erection of Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings;-And To make all Laws which shall be necessary and proper for carrying into Execution the foregoing Powers, and all other Powers vested by this Constitution in the Government of the United States, or in any Department or Officer thereof. ## Section 9 The Migration or Importation of such Persons as any of the States now existing shall think proper to admit, shall not be prohibited by the Congress prior to the Year one thousand eight hundred and eight, but a Tax or duty may be imposed on such Importation, not exceeding ten dollars for each Person. The Privilege of the Writ of Habeas Corpus shall not be suspended, unless when in Cases of Rebellion or Invasion the public Safety may require it. No Bill of Attainder or ex post facto Law shall be passed. No Capitation, or other direct, Tax shall be laid, unless in Proportion to the Census or enumeration herein before directed to be taken. No Tax or Duty shall be laid on Articles exported from any State. No Preference shall be given by any Regulation of Commerce or Revenue to the Ports of one State over those of another; nor shall Vessels bound to, or from, one State, be obliged to enter, clear, or pay Duties in another. No Money shall be drawn from the Treasury, but in Consequence of Appropriations made by Law; and a regular Statement and Account of the Receipts and Expenditures of all public Money shall be published from time to time. No Title of Nobility shall be granted by the United States: And no Person holding any Office of Profit or Trust under them, shall, without the Consent of the Congress, accept of any present, Emolument, Office, or Title, of any kind whatever, from any King, Prince, or foreign State. ## Section 10 No State shall enter into any Treaty, Alliance, or Confederation; grant Letters of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder, ex post facto Law, or Law impairing the Obligation of Contracts, or grant any Title of Nobility. No State shall, without the Consent of the Congress, lay any Imposts or Duties on Imports or Exports, except what may be absolutely necessary for executing its inspection Laws: and the net Produce of all Duties and Imposts, laid by any State on Imports or Exports, shall be for the Use of the Treasury of the United States; and all such Laws shall be subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, keep Troops, or Ships of War in time of Peace, enter into any Agreement or Compact with another State, or with a foreign Power, or engage in War, unless actually invaded, or in such imminent Danger as will not admit of delay. # Article II ## Section 1 The executive Power shall be vested in a President of the United States of America. He shall hold his Office during the Term of four Years, and, together with the Vice President, chosen for the same Term, be elected, as follows: Each State shall appoint, in such Manner as the Legislature thereof may direct, a Number of Electors, equal to the whole Number of Senators and Representatives to which the State may be entitled in the Congress: but no Senator or Representative, or Person holding an Office of Trust or Profit under the United States, shall be appointed an Elector. The Electors shall meet in their respective States, and vote by Ballot for two Persons, of whom one at least shall not be an Inhabitant of the same State with themselves. And they shall make a List of all the Persons voted for, and of the Number of Votes for each; which List they shall sign and certify, and transmit sealed to the Seat of the Government of the United States, directed to the President of the Senate. The President of the Senate shall, in the Presence of the Senate and House of Representatives, open all the Certificates, and the Votes shall then be counted. The Person having the greatest Number of Votes shall be the President, if such Number be a Majority of the whole Number of Electors appointed; and if there be more than one who have such Majority, and have an equal Number of Votes, then the House of Representatives shall immediately chuse by Ballot one of them for President; and if no Person have a Majority, then from the five highest on the List the said House shall in like Manner chuse the President. But in chusing the President, the Votes shall be taken by States, the Representatives from each State having one Vote; a quorum for this Purpose shall consist of a Member or Members from two thirds of the States, and a Majority of all the States shall be necessary to a Choice. In every Case, after the Choice of the President, the Person having the greatest Number of Votes of the Electors shall be the Vice President. But if there should remain two or more who have equal Votes, the Senate shall chuse from them by Ballot the Vice-President. The Congress may determine the Time of chusing the Electors, and the Day on which they shall give their Votes; which Day shall be the same throughout the United States. No Person except a natural born Citizen, or a Citizen of the United States, at the time of the Adoption of this Constitution, shall be eligible to the Office of President; neither shall any person be eligible to that Office who shall not have attained to the Age of thirty five Years, and been fourteen Years a Resident within the United States. In Case of the Removal of the President from Office, or of his Death, Resignation, or Inability to discharge the Powers and Duties of the said Office, the Same shall devolve on the Vice President, and the Congress may by Law provide for the Case of Removal, Death, Resignation or Inability, both of the President and Vice President, declaring what Officer shall then act as President, and such Officer shall act accordingly, until the Disability be removed, or a President shall be elected. The President shall, at stated Times, receive for his Services, a Compensation, which shall neither be encreased nor diminished during the Period for which he shall have been elected, and he shall not receive within that Period any other Emolument from the United States, or any of them. Before he enter on the Execution of his Office, he shall take the following Oath or Affirmation:-"I do solemnly swear (or affirm) that I will faithfully execute the Office of President of the United States, and will to the best of my Ability, preserve, protect and defend the Constitution of the United States." ## Section 2 The President shall be Commander in Chief of the Army and Navy of the United States, and of the Militia of the several States, when called into the actual Service of the United States; he may require the Opinion, in writing, of the principal Officer in each of the executive Departments, upon any Subject relating to the Duties of their respective Offices, and he shall have Power to Grant Reprieves and Pardons for Offences against the United States, except in Cases of Impeachment. He shall have Power, by and with the Advice and Consent of the Senate, to make Treaties, provided two thirds of the Senators present concur; and he shall nominate, and by and with the Advice and Consent of the Senate, shall appoint Ambassadors, other public Ministers and Consuls, Judges of the supreme Court, and all other Officers of the United States, whose Appointments are not herein otherwise provided for, and which shall be established by Law: but the Congress may by Law vest the Appointment of such inferior Officers, as they think proper, in the President alone, in the Courts of Law, or in the Heads of Departments. The President shall have Power to fill up all Vacancies that may happen during the Recess of the Senate, by granting Commissions which shall expire at the End of their next Session. ## Section 3 He shall from time to time give to the Congress Information on the State of the Union, and recommend to their Consideration such Measures as he shall judge necessary and expedient; he may, on extraordinary Occasions, convene both Houses, or either of them, and in Case of Disagreement between them, with Respect to the Time of Adjournment, he may adjourn them to such Time as he shall think proper; he shall receive Ambassadors and other public Ministers; he shall take Care that the Laws be faithfully executed, and shall Commission all the Officers of the United States. ## Section 4 The President, Vice President and all Civil Officers of the United States, shall be removed from Office on Impeachment for, and Conviction of, Treason, Bribery, or other high Crimes and Misdemeanors. # Article III ## Section 1 The judicial Power of the United States, shall be vested in one supreme Court, and in such inferior Courts as the Congress may from time to time ordain and establish. The Judges, both of the supreme and inferior Courts, shall hold their Offices during good Behaviour, and shall, at stated Times, receive for their Services, a Compensation, which shall not be diminished during their Continuance in Office. ## Section 2 The judicial Power shall extend to all Cases, in Law and Equity, arising under this Constitution, the Laws of the United States, and Treaties made, or which shall be made, under their Authority; -- to all Cases affecting Ambassadors, other public ministers and Consuls; -- to all Cases of admiralty and maritime Jurisdiction; -- to Controversies to which the United States shall be a Party; -- to Controversies between two or more States; -- between a State and Citizens of another State; -- between Citizens of different States; -- between Citizens of the same State claiming Lands under Grants of different States, and between a State, or the Citizens thereof, and foreign States, Citizens or Subjects. In all Cases affecting Ambassadors, other public Ministers and Consuls, and those in which a State shall be Party, the supreme Court shall have original Jurisdiction. In all the other Cases before mentioned, the supreme Court shall have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and under such Regulations as the Congress shall make. The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and such Trial shall be held in the State where the said Crimes shall have been committed; but when not committed within any State, the Trial shall be at such Place or Places as the Congress may by Law have directed. ## Section 3 Treason against the United States, shall consist only in levying War against them, or in adhering to their Enemies, giving them Aid and Comfort. No Person shall be convicted of Treason unless on the Testimony of two Witnesses to the same overt Act, or on Confession in open Court. The Congress shall have Power to declare the Punishment of Treason, but no Attainder of Treason shall work Corruption of Blood, or Forfeiture except during the Life of the Person attainted. # Article IV ## Section 1 Full Faith and Credit shall be given in each State to the public Acts, Records, and judicial Proceedings of every other State. And the Congress may by general Laws prescribe the Manner in which such Acts, Records and Proceedings shall be proved, and the Effect thereof. ## Section 2 The Citizens of each State shall be entitled to all Privileges and Immunities of Citizens in the several States. A Person charged in any State with Treason, Felony, or other Crime, who shall flee from Justice, and be found in another State, shall on Demand of the executive Authority of the State from which he fled, be delivered up, to be removed to the State having Jurisdiction of the Crime. No Person held to Service or Labour in one State, under the Laws thereof, escaping into another, shall, in Consequence of any Law or Regulation therein, be discharged from such Service or Labour, but shall be delivered up on Claim of the Party to whom such Service or Labour may be due. ## Section 3 New States may be admitted by the Congress into this Union; but no new State shall be formed or erected within the Jurisdiction of any other State; nor any State be formed by the Junction of two or more States, or Parts of States, without the Consent of the Legislatures of the States concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and Regulations respecting the Territory or other Property belonging to the United States; and nothing in this Constitution shall be so construed as to Prejudice any Claims of the United States, or of any particular State. ## Section 4 The United States shall guarantee to every State in this Union a Republican Form of Government, and shall protect each of them against Invasion; and on Application of the Legislature, or of the Executive (when the Legislature cannot be convened) against domestic Violence. # Article V The Congress, whenever two thirds of both Houses shall deem it necessary, shall propose Amendments to this Constitution, or, on the Application of the Legislatures of two thirds of the several States, shall call a Convention for proposing Amendments, which, in either Case, shall be valid to all Intents and Purposes, as Part of this Constitution, when ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight shall in any Manner affect the first and fourth Clauses in the Ninth Section of the first Article; and that no State, without its Consent, shall be deprived of its equal Suffrage in the Senate. # Article VI All Debts contracted and Engagements entered into, before the Adoption of this Constitution, shall be as valid against the United States under this Constitution, as under the Confederation. This Constitution, and the Laws of the United States which shall be made in Pursuance thereof; and all Treaties made, or which shall be made, under the Authority of the United States, shall be the supreme Law of the Land; and the Judges in every State shall be bound thereby, any Thing in the Constitution or Laws of any state to the Contrary notwithstanding. The Senators and Representatives before mentioned, and the Members of the several State Legislatures, and all executive and judicial Officers, both of the United States and of the several States, shall be bound by Oath or Affirmation, to support this Constitution; but no religious Test shall ever be required as a Qualification to any Office or public Trust under the United States. # Article VII The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying the Same. ack-v3.5.0/t/context.t0000644000175100017510000002460514023027176013242 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 19; use lib 't'; use Util; prep_environment(); # Checks also beginning of file. BEFORE: { my @expected = line_split( <<'HERE' ); I met a traveller from an antique land -- Stand in the desert... Near them, on the sand, Half sunk, a shattered visage lies, whose frown, HERE my $regex = 'a'; my @files = qw( t/text/ozymandias.txt ); my @args = ( '-w', '-B1', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - before" ); } BEFORE_WITH_LINE_NO: { my $target_file = reslash( 't/text/ozymandias.txt' ); my @expected = line_split( <<"HERE" ); $target_file-1-I met a traveller from an antique land $target_file-2-Who said: Two vast and trunkless legs of stone $target_file:3:Stand in the desert... Near them, on the sand, -- $target_file-12-Nothing beside remains. Round the decay $target_file-13-Of that colossal wreck, boundless and bare $target_file:14:The lone and level sands stretch far away. HERE my $regex = 'sand'; my @files = qw( t/text/ozymandias.txt t/text/bill-of-rights.txt ); # So we don't pick up constitution.txt my @args = ( '--sort-files', '-B2', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - before with line numbers" ); } # Checks also end of file. AFTER: { my @expected = line_split( <<'HERE' ); The lone and level sands stretch far away. HERE my $regex = 'sands'; my @files = qw( t/text/ozymandias.txt ); my @args = ( '-A2', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - after" ); } # Context defaults to 2. CONTEXT_DEFAULT: { my @expected = line_split( <<'HERE' ); "Yes,"I said, "let us be gone." "For the love of God, Montresor!" "Yes," I said, "for the love of God!" HERE my $regex = 'Montresor'; my @files = qw( t/text/amontillado.txt ); my @args = ( '-w', '-C', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - context defaults to 2" ); } # Try context 1. CONTEXT_ONE: { my @expected = line_split( <<'HERE' ); "For the love of God, Montresor!" HERE push( @expected, '' ); # Since split eats the last line. my $regex = 'Montresor'; my @files = qw( t/text/amontillado.txt ); my @args = ( '-w', '-C', 1, $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - context=1" ); } # --context=0 means no context. CONTEXT_ONE: { my @expected = line_split( <<'HERE' ); "For the love of God, Montresor!" HERE my $regex = 'Montresor'; my @files = qw( t/text/amontillado.txt ); my @args = ( '-w', '-C', 0, $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - context=0" ); } # -1 must not stop the ending context from displaying. CONTEXT_DEFAULT: { my @expected = line_split( <<'HERE' ); or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the Government for a redress of grievances. HERE my $regex = 'right'; my @files = qw( t/text/bill-of-rights.txt ); my @args = ( '-1', '-C1', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with -1" ); } # -C with overlapping contexts (adjacent lines) CONTEXT_OVERLAPPING: { my @expected = line_split( <<'HERE' ); This is line 03 This is line 04 This is line 05 This is line 06 This is line 07 This is line 08 HERE my $regex = '05|06'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '-C', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with overlapping contexts" ); } # -C with contexts that touch. CONTEXT_ADJACENT: { my @expected = line_split( <<'HERE' ); This is line 01 This is line 02 This is line 03 This is line 04 This is line 05 This is line 06 This is line 07 This is line 08 This is line 09 This is line 10 HERE my $regex = '03|08'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '-C', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with contexts that touch" ); } # -C with contexts that just don't touch. CONTEXT_NONADJACENT: { my @expected = line_split( <<'HERE' ); This is line 01 This is line 02 This is line 03 This is line 04 This is line 05 -- This is line 07 This is line 08 This is line 09 This is line 10 This is line 11 HERE my $regex = '03|09'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '-C', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with contexts that just don't touch" ); } CONTEXT_OVERLAPPING_COLOR: { my $match_start = "\e[30;43m"; my $match_end = "\e[0m"; my $line_end = "\e[0m\e[K"; my @expected = line_split( <<"HERE" ); This is line 03 This is line 04 This is line ${match_start}05${match_end}${line_end} This is line ${match_start}06${match_end}${line_end} This is line 07 This is line 08 HERE my $regex = '05|06'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '--color', '-C', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with overlapping contexts" ); } CONTEXT_OVERLAPPING_COLOR_BEFORE: { my $match_start = "\e[30;43m"; my $match_end = "\e[0m"; my $line_end = "\e[0m\e[K"; my @expected = line_split( <<"HERE" ); This is line 03 This is line 04 This is line ${match_start}05${match_end}${line_end} This is line ${match_start}06${match_end}${line_end} HERE my $regex = '05|06'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '--color', '-B2', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with overlapping contexts" ); } CONTEXT_OVERLAPPING_COLOR_AFTER: { my $match_start = "\e[30;43m"; my $match_end = "\e[0m"; my $line_end = "\e[0m\e[K"; my @expected = line_split( <<"HERE" ); This is line ${match_start}05${match_end}${line_end} This is line ${match_start}06${match_end}${line_end} This is line 07 This is line 08 HERE my $regex = '05|06'; my @files = qw( t/text/numbered-text.txt ); my @args = ( '--color', '-A2', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with overlapping contexts" ); } # -m3 should work properly and show only 3 matches with correct context # even though there is a 4th match in the after context of the third match # ("ratifying" in the last line) CONTEXT_MAX_COUNT: { my @expected = line_split( <<'HERE' ); ratified by the Legislatures of three fourths of the several States, or by Conventions in three fourths thereof, as the one or the other Mode of Ratification may be proposed by the Congress; Provided that no Amendment which may be made prior to the Year One thousand eight hundred and eight -- The Ratification of the Conventions of nine States, shall be sufficient for the Establishment of this Constitution between the States so ratifying HERE my $regex = 'ratif'; my @files = qw( t/text/constitution.txt ); my @args = ( '-i', '-m3', '-A1', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex with -m3" ); } # Highlighting works with context. HIGHLIGHTING: { my @ack_args = qw( wretch -i -C5 --color ); my @results = pipe_into_ack( 't/text/raven.txt', @ack_args ); my @escaped_lines = grep { /\e/ } @results; is( scalar @escaped_lines, 1, 'Only one line highlighted' ); is( scalar @results, 11, 'Expecting altogether 11 lines back' ); } # Grouping works with context (single file). GROUPING_SINGLE_FILE: { my $target_file = reslash( 't/etc/shebang.py.xxx' ); my @expected = line_split( <<"HERE" ); $target_file 1:#!/usr/bin/python HERE my $regex = 'python'; my @args = ( '-t', 'python', '--group', '-C', $regex ); ack_lists_match( [ @args ], \@expected, "Looking for $regex in Python files with grouping" ); } # Grouping works with context and multiple files. # i.e. a separator line between different matches in the same file and no separator between files GROUPING_MULTIPLE_FILES: { my @expected = line_split( <<"HERE" ); t/text/amontillado.txt 258-As I said these words I busied myself among the pile of bones of 259:which I have before spoken. Throwing them aside, I soon uncovered t/text/raven.txt 31-But the silence was unbroken, and the stillness gave no token, 32:And the only word there spoken was the whispered word, "Lenore?" -- 70- 71:Startled at the stillness broken by reply so aptly spoken, -- 114-"Get thee back into the tempest and the Night's Plutonian shore! 115:Leave no black plume as a token of that lie thy soul hath spoken! HERE my $regex = 'spoken'; my @files = qw( t/text/ ); my @args = ( '--group', '-B1', '--sort-files', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex in multiple files with grouping" ); } # See https://github.com/beyondgrep/ack2/issues/326 and links there for details. WITH_COLUMNS_AND_CONTEXT: { my @files = qw( t/text/ ); my @expected = line_split( <<'HERE' ); t/text/bill-of-rights.txt-1-# Amendment I t/text/bill-of-rights.txt-2- t/text/bill-of-rights.txt-3-Congress shall make no law respecting an establishment of religion, t/text/bill-of-rights.txt:4:60:or prohibiting the free exercise thereof; or abridging the freedom of t/text/bill-of-rights.txt-5-speech, or of the press; or the right of the people peaceably to assemble, t/text/bill-of-rights.txt-6-and to petition the Government for a redress of grievances. t/text/bill-of-rights.txt-7- t/text/bill-of-rights.txt-8-# Amendment II t/text/bill-of-rights.txt-9- -- t/text/gettysburg.txt-18-fought here have thus far so nobly advanced. It is rather for us to be t/text/gettysburg.txt-19-here dedicated to the great task remaining before us -- that from these t/text/gettysburg.txt-20-honored dead we take increased devotion to that cause for which they gave t/text/gettysburg.txt-21-the last full measure of devotion -- that we here highly resolve that t/text/gettysburg.txt-22-these dead shall not have died in vain -- that this nation, under God, t/text/gettysburg.txt:23:27:shall have a new birth of freedom -- and that government of the people, t/text/gettysburg.txt-24-by the people, for the people, shall not perish from the earth. HERE my $regex = 'freedom'; my @args = ( '--column', '-C5', '-H', '--sort-files', $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex" ); } done_testing(); exit 0; ack-v3.5.0/t/ack-w.t0000644000175100017510000001530314023027176012553 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 15; use lib 't'; use Util; use Barfly; prep_environment(); my $ACK = $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'ack'; Barfly->run_tests( 't/ack-w.barfly' ); subtest '-w with trailing metachar \w' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = ( 'Milit\w\w', qw( -w -h --sort-files ) ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for militia with metacharacters' ); }; subtest '-w with trailing dot' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = ( 'Milit..', qw( -w -h --sort-files ) ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Milit..' ); }; subtest 'Begins and ends with word char' => sub { plan tests => 1; # Normal case of whole word match. my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = qw( Militia -w -h --sort-files ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Militia as whole word' ); }; subtest 'Ends with grouping parens' => sub { plan tests => 1; # The last character of the regexp is not a word, disabling the word boundary check at the end of the match. my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = ( 'Militia()', qw( -w -h --sort-files ) ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Militia with word flag, but regexp does not end with word char' ); }; subtest 'Begins with grouping parens' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = ( '()Militia', qw( -w -h --sort-files ) ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Militia with word flag, but regexp does not begin with word char' ); }; subtest 'Wrapped in grouping parens' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, cases arising in the land or naval forces, or in the Militia, when in HERE my @files = qw( t/text/bill-of-rights.txt ); my @args = ( '(Militia)', qw( -w -h --sort-files ) ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Militia with word flag, but regexp does not begin or end with word char' ); }; # Test for issue ack2#443 subtest 'Alternating numbers' => sub { plan tests => 1; my @expected = (); my @files = qw( t/text/number.txt ); my @args = ( '650|660|670|680', '-w' ); ack_lists_match( [ @args, @files ], \@expected, 'Alternations should also respect boundaries when using -w' ); }; # In ack3, we try to warn people if they are misusing -w. subtest '-w warnings' => sub { my ($good,$bad,$inv) = _get_good_and_bad(); plan tests => @{$good} + @{$bad} + @{$inv}; my $happy = reslash( 't/text/ozymandias.txt' ); for my $pattern ( @{$good} ) { subtest "Good example: $pattern" => sub { plan tests => 1; my ( undef, $stderr ) = run_ack_with_stderr( $pattern, '-w', $happy ); # Don't care what stdout is. is_empty_array( $stderr, 'Should not trigger any warnings' ); } } for my $pattern ( @{$bad} ) { subtest "Bad example: $pattern" => sub { plan tests => 3; # Add the -- because the pattern may have hyphens. my ( $stdout, $stderr ) = run_ack_with_stderr( '-w', '--', $pattern, $happy ); is_empty_array( $stdout, 'Should have no output' ); is( scalar @{$stderr}, 1, 'One warning' ); like( $stderr->[0], qr/$ACK: -w will not do the right thing/, 'Got the correct warning' ); }; } for my $pattern ( @{$inv} ) { subtest "Invalid regex: $pattern" => sub { plan tests => 3; # Add the -- because the pattern may have hyphens. my ( $stdout, $stderr ) = run_ack_with_stderr( '-w', '--', $pattern, $happy ); is_empty_array( $stdout, 'Should have no output' ); is( scalar @{$stderr}, 3, 'One warning' ); like( $stderr->[0], qr/$ACK: Invalid regex '\Q$pattern'/ ); }; } }; sub _get_good_and_bad { # BAD = should throw a warning with -w # OK = should not throw a warning with -w # INV = is an invalid regex whether with -w or not my @examples = line_split( <<'HERE' ); # Anchors BAD $foo BAD foo^ BAD ^foo BAD foo$ # Dot OK foo. OK .foo # Parentheses OK (set|get)_foo OK foo_(id|name) OK func() OK (all in one group) INV )start with closing paren INV end with opening paren( BAD end with an escaped closing paren\) # Character classes OK [sg]et OK foo[lt] OK [one big character class] OK [multiple][character][classes] BAD ]starting with a closing bracket INV ending with an opening bracket[ BAD ending with an escaped closing bracket \] # Quantifiers OK thpppt{1,5} BAD }starting with an closing curly brace BAD ending with an escaped closing curly brace\} OK foo+ BAD foo\+ INV +foo OK foo* BAD foo\* INV *foo OK foo? BAD foo\? INV ?foo # Miscellaneous debris BAD -foo BAD foo- BAD &mpersand BAD ampersand& INV function( BAD ->method BAD BAD =14 BAD /slashes/ BAD ::Class::Whatever BAD Class::Whatever:: OK Class::Whatever HERE my $good = []; my $bad = []; my $inv = []; for my $line ( @examples ) { $line =~ s/\s*$//; if ( $line eq '' || $line =~ /^#/ ) { next; } elsif ( $line =~ /^OK\s+(.+)/ ) { push( @{$good}, $1 ); } elsif ( $line =~ /BAD\s+(.+)/ ) { push( @{$bad}, $1 ); } elsif ( $line =~ /INV\s+(.+)/ ) { push( @{$inv}, $1 ); } else { die "Invalid line: $line"; } } return ($good, $bad, $inv); } done_testing(); exit 0; ack-v3.5.0/t/double-hyphen.t0000644000175100017510000000147514023027176014321 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 1; use lib 't'; use Util; prep_environment(); subtest 'Double-hyphen allows hyphens after' => sub { plan tests => 1; my $cask = reslash( 't/text/amontillado.txt' ); my $bill = reslash( 't/text/bill-of-rights.txt' ); my @expected = line_split( <<"HERE" ); $cask:284:to the yells of him who clamored. I re-echoed--I aided--I surpassed $cask:327:I re-erected the old rampart of bones. For the half of a century $bill:53:fact tried by a jury, shall be otherwise re-examined in any Court of HERE my @files = qw( t/text/ ); my @args = ( '-i', '--sort', '--', '-E' ); # The -i must be in force for the /-E/ to find "-e" ack_lists_match( [ @args, @files ], \@expected, 'Looking for militia with metacharacters' ); }; done_testing(); exit 0; ack-v3.5.0/t/longopts.t0000644000175100017510000000734514023027176013425 0ustar andyandy#!perl use strict; use warnings; =head1 DESCRIPTION This tests whether ack's command line options work as expected. =cut use Test::More; plan tests => 52; use lib 't'; use Util; prep_environment(); # Help for my $arg ( qw( --help ) ) { my @sections = ( 'File select actions:', 'File listing actions:', 'Searching:', 'Search output:', 'File presentation:', 'File finding:', 'File inclusion/exclusion:', 'File type inclusion/exclusion:', 'File type specification:', 'Miscellaneous:', 'Filter specifications:', ); my @args = ($arg); my $results = run_ack( @args ); for my $section ( @sections ) { like( $results, qr{^Usage:.*$section}ms, qq{Found "$section" section} ); } } # Version for my $arg ( qw( --version ) ) { my @args = ($arg); my $results = run_ack( @args ); like( $results, qr{ ^ack .* Copyright }xs, qq{$arg output is correct} ); } # Ignore case for my $arg ( qw( -i --ignore-case ) ) { my @args = ( $arg, 'upper case' ); my @files = ( 't/swamp/options.pl' ); my $results = run_ack( @args, @files ); like( $results, qr{UPPER CASE}, qq{$arg works correctly for ascii} ); } SMART_CASE: { my @files = 't/swamp/options.pl'; for my $opt ( '-S', '--smart-case' ) { like( +run_ack( $opt, 'upper case', @files ), qr{UPPER CASE}, qq{$opt turn on ignore-case when PATTERN has no upper} ); unlike( +run_ack( $opt, 'Upper case', @files ), qr{UPPER CASE}, qq{$opt does nothing when PATTERN has upper} ); like( +run_ack( $opt, '-i', 'UpPer CaSe', @files ), qr{UPPER CASE}, qq{-i overrides $opt, forcing ignore case, even when PATTERN has upper} ); } } # Invert match # This test was changed from using unlike to using like because # old versions of Test::More::unlike (before 0.48_2) cannot # work with multiline output (which ack produces in this case). for my $arg ( qw( -v --invert-match ) ) { my @args = ( $arg, 'use warnings' ); my @files = qw( t/swamp/options.pl ); my $results = run_ack( @args, @files ); like( $results, qr{use strict;\n\n=head1 NAME}, # no 'use warnings' in between here qq{$arg works correctly} ); } # Word regexp for my $arg ( qw( -w --word-regexp ) ) { my @args = ( $arg, 'word' ); my @files = qw( t/swamp/options.pl ); my $results = run_ack( @args, @files ); like( $results, qr{ word }, qq{$arg ignores non-words} ); unlike( $results, qr{notaword}, qq{$arg ignores non-words} ); } # Literal for my $arg ( qw( -Q --literal ) ) { my @args = ( $arg, '[abc]' ); my @files = qw( t/swamp/options.pl ); my $results = run_ack( @args, @files ); like( $results, qr{\Q[abc]\E}, qq{$arg matches a literal string} ); } my $expected = reslash( 't/swamp/options.pl' ); # Files with matches for my $arg ( qw( -l --files-with-matches ) ) { my @args = ( $arg, 'use strict' ); my @files = qw( t/swamp/options.pl ); my $results = run_ack( @args, @files ); like( $results, qr{\Q$expected}, qq{$arg prints matching files} ); } # Files without match for my $arg ( qw( -L --files-without-matches ) ) { my @args = ( $arg, 'use snorgledork' ); my @files = qw( t/swamp/options.pl ); my $results = run_ack( @args, @files ); like( $results, qr{\Q$expected}, qq{$arg prints matching files} ); } ack-v3.5.0/t/trailing-whitespace.t0000644000175100017510000000437414023027176015522 0ustar andyandy#!perl use warnings; use strict; use Test::More; use lib 't'; use Util; plan tests => 4; prep_environment(); subtest 'whitespace+dollar normal' => sub { plan tests => 4; my @expected = (); my @files = qw( t/text/ ); for my $context ( undef, '-A', '-B', '-C' ) { my @args = qw( \s$ ); push( @args, $context ) if $context; ack_sets_match( [ @args, @files ], \@expected, '\s$ should not match the newlines at the end of a line' ); } }; subtest 'whitespace+dollar with -l' => sub { plan tests => 1; my @expected = (); my @files = qw( t/text/ ); my @args = qw( \s$ -l ); ack_sets_match( [ @args, @files ], \@expected, '\s$ should not match the newlines at the end of a line' ); }; subtest 'whitespace+dollar with -L' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt HERE my @files = qw( t/text/ ); my @args = qw( \s$ -L --sort ); ack_sets_match( [ @args, @files ], \@expected, '\s$ should not match the newlines at the end of a line' ); }; subtest 'whitespace+dollar with -v' => sub { plan tests => 4; my @expected = line_split( <<'HERE' ); I met a traveller from an antique land Who said: Two vast and trunkless legs of stone Stand in the desert... Near them, on the sand, Half sunk, a shattered visage lies, whose frown, And wrinkled lip, and sneer of cold command, Tell that its sculptor well those passions read Which yet survive, stamped on these lifeless things, The hand that mocked them, and the heart that fed: And on the pedestal these words appear: 'My name is Ozymandias, king of kings: Look on my works, ye Mighty, and despair!' Nothing beside remains. Round the decay Of that colossal wreck, boundless and bare The lone and level sands stretch far away. HERE my @files = qw( t/text/ozymandias.txt ); for my $context ( undef, '-A', '-B', '-C' ) { my @args = qw( \s$ -v ); push( @args, $context ) if $context; ack_sets_match( [ @args, @files ], \@expected, '\s$ should not match the newlines at the end of a line' ); } }; done_testing(); exit 0; ack-v3.5.0/t/anchored.t0000644000175100017510000000606414023027176013340 0ustar andyandy#!perl # Make sure beginning-of-line anchor works use strict; use warnings; use Test::More tests => 3; use lib 't'; use Util; prep_environment(); my @files = qw( t/text/constitution.txt ); FRONT_ANCHORED: { my @args = qw( --sort-files -h -i ^congress ); my @expected = line_split( <<'HERE' ); Congress prior to the Year one thousand eight hundred and eight, but HERE ack_lists_match( [ @args, @files ], \@expected, 'Looking for front-anchored "congress"' ); } BACK_ANCHORED: { my @args = qw( --sort-files -h -i congress$ ); my @expected = line_split( <<'HERE' ); All legislative Powers herein granted shall be vested in a Congress Fact, with such Exceptions, and under such Regulations as the Congress Records, and judicial Proceedings of every other State. And the Congress HERE ack_sets_match( [ @args, @files ], \@expected, 'Looking for back-anchored "congress"' ); } UNANCHORED: { my @args = qw( --sort-files -h -i congress ); my @expected = line_split( <<'HERE' ); All legislative Powers herein granted shall be vested in a Congress the first Meeting of the Congress of the United States, and within thereof; but the Congress may at any time by Law make or alter such The Congress shall assemble at least once in every Year, and such Neither House, during the Session of Congress, shall, without the Consent a Law, in like Manner as if he had signed it, unless the Congress by The Congress shall have Power To lay and collect Taxes, Duties, Imposts the discipline prescribed by Congress; particular States, and the Acceptance of Congress, become the Seat of Congress prior to the Year one thousand eight hundred and eight, but the Consent of the Congress, accept of any present, Emolument, Office, No State shall, without the Consent of the Congress, lay any Imposts or subject to the Revision and Control of the Congress. No State shall, without the Consent of Congress, lay any Duty of Tonnage, and Representatives to which the State may be entitled in the Congress: The Congress may determine the Time of chusing the Electors, and the Office, the Same shall devolve on the Vice President, and the Congress may be established by Law: but the Congress may by Law vest the Appointment He shall from time to time give to the Congress Information on the State Court, and in such inferior Courts as the Congress may from time to Fact, with such Exceptions, and under such Regulations as the Congress shall be at such Place or Places as the Congress may by Law have directed. The Congress shall have Power to declare the Punishment of Treason, but Records, and judicial Proceedings of every other State. And the Congress New States may be admitted by the Congress into this Union; but no new concerned as well as of the Congress. The Congress shall have Power to dispose of and make all needful Rules and The Congress, whenever two thirds of both Houses shall deem it necessary, Ratification may be proposed by the Congress; Provided that no Amendment HERE ack_lists_match( [ @args, @files ], \@expected, 'Looking for unanchored congress' ); } done_testing(); exit 0; ack-v3.5.0/t/etc/0000755000175100017510000000000014023040526012127 5ustar andyandyack-v3.5.0/t/etc/shebang.sh.xxx0000644000175100017510000000001614023027176014723 0ustar andyandy#!/usr/bin/sh ack-v3.5.0/t/etc/shebang.foobar.xxx0000644000175100017510000000002214023027176015556 0ustar andyandy#!/usr/bin/foobar ack-v3.5.0/t/etc/shebang.empty.xxx0000644000175100017510000000000014023027176015440 0ustar andyandyack-v3.5.0/t/etc/shebang.py.xxx0000644000175100017510000000002214023027176014736 0ustar andyandy#!/usr/bin/python ack-v3.5.0/t/etc/buttonhook.xml.xxx0000644000175100017510000000047314023027176015705 0ustar andyandy ack-v3.5.0/t/etc/shebang.pl.xxx0000644000175100017510000000015214023027176014725 0ustar andyandy#!/usr/bin/perl # NOTE: This must stay a very short file so that C<-B $open_fh> will # think it's binary. ack-v3.5.0/t/etc/shebang.php.xxx0000644000175100017510000000001714023027176015101 0ustar andyandy#!/usr/bin/php ack-v3.5.0/t/etc/shebang.rb.xxx0000644000175100017510000000002014023027176014707 0ustar andyandy#!/usr/bin/ruby ack-v3.5.0/t/context-with-newlines.t0000644000175100017510000000100414023027176016021 0ustar andyandy#!perl # https://github.com/beyondgrep/ack2/issues/522 use strict; use warnings; use Test::More tests => 4; use lib 't'; use Util; prep_environment(); my @stdout; @stdout = run_ack("use strict;\nuse warnings", 't/swamp'); is_empty_array( \@stdout, 'An embedded newline in the search regex should never match anything' ); @stdout = run_ack('-A', '1', "use strict;\nuse warnings", 't/swamp'); is_empty_array( \@stdout, 'An embedded newline in the search regex should never match anything, even with context' ); ack-v3.5.0/t/ack-ignore-dir.t0000644000175100017510000002024014023027176014340 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 45; use File::Spec; use lib 't'; use Util; prep_environment(); my @files_mentioning_apples = qw( t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/CVS/fruit t/swamp/groceries/another_subdir/CVS/junk t/swamp/groceries/another_subdir/RCS/fruit t/swamp/groceries/another_subdir/RCS/junk t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/CVS/fruit t/swamp/groceries/dir.d/CVS/junk t/swamp/groceries/dir.d/RCS/fruit t/swamp/groceries/dir.d/RCS/junk t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/CVS/fruit t/swamp/groceries/CVS/junk t/swamp/groceries/RCS/fruit t/swamp/groceries/RCS/junk ); my @std_ignore = qw( RCS CVS ); my( @expected, @results, $test_description ); sub set_up_assertion_that_these_options_will_ignore_those_directories { my( $options, $ignored_directories, $optional_test_description ) = @_; local $Test::Builder::Level = $Test::Builder::Level + 1; $test_description = $optional_test_description || join( ' ', @{$options} ); my $filter = join( '|', @{$ignored_directories} ); @expected = grep { ! m{/(?:$filter)/} } @files_mentioning_apples; @results = run_ack( @{$options}, '--noenv', '-l', 'apple', 't/swamp' ); # ignore everything in .svn directories my $svn_regex = quotemeta File::Spec->catfile( '', '.svn', '' ); # the respective filesystem equivalent of '/.svn/' @results = grep { ! m/$svn_regex/ } @results; return; } DASH_IGNORE_DIR: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=subdir', ], [ @std_ignore, 'subdir', ], ); sets_match( \@results, \@expected, $test_description ); } DASH_IGNORE_DIR_WITH_SLASH: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=subdir/', ], [ @std_ignore, 'subdir', ], ); sets_match( \@results, \@expected, $test_description ); } DASH_IGNORE_DIR_MULTIPLE_TIMES: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=subdir', '--ignore-dir=another_subdir', ], [ @std_ignore, 'subdir', 'another_subdir', ], ); sets_match( \@results, \@expected, $test_description ); } DASH_NOIGNORE_DIR: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=CVS', ], [ 'RCS', ], ); sets_match( \@results, \@expected, $test_description ); } DASH_NOIGNORE_DIR_MULTIPLE_TIMES: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=CVS', '--noignore-dir=RCS', ], [ ], ); sets_match( \@results, \@expected, $test_description ); } DASH_IGNORE_DIR_WITH_DASH_NOIGNORE_DIR: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=CVS', '--ignore-dir=subdir', ], [ 'RCS', 'subdir', ], ); sets_match( \@results, \@expected, $test_description ); } LAST_ONE_LISTED_WINS: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=CVS', '--ignore-dir=CVS', ], [ @std_ignore, ], ); sets_match( \@results, \@expected, $test_description ); set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=CVS', '--ignore-dir=CVS', '--noignore-dir=CVS', ], [ 'RCS', ], ); sets_match( \@results, \@expected, $test_description ); set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=subdir', '--noignore-dir=subdir', ], [ @std_ignore, ], ); sets_match( \@results, \@expected, $test_description ); set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=subdir', '--noignore-dir=subdir', '--ignore-dir=subdir', ], [ @std_ignore, 'subdir', ], ); sets_match( \@results, \@expected, $test_description ); } DASH_IGNORE_DIR_IGNORES_RELATIVE_PATHS: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=' . File::Spec->catdir('t' ,'swamp', 'groceries' , 'another_subdir'), ], [ @std_ignore, 'another_subdir', ], 'ignore relative paths instead of just directory names', ); sets_match( \@results, \@expected, $test_description ); } NOIGNORE_SUBDIR_WINS: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=another_subdir', '--noignore-dir=CVS' ], [ 'RCS', 'another_subdir(?!/CVS)' ], ); sets_match( \@results, \@expected, $test_description ); } IGNORE_DIR_MATCH: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=match:/\w_subdir/' ], [ @std_ignore, 'another_subdir', ], ); sets_match( \@results, \@expected, $test_description ); } IGNORE_DIR_EXT: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=ext:d' ], [ @std_ignore, 'dir.d', ], ); sets_match( \@results, \@expected, $test_description ); } IGNORE_DIR_FIRSTMATCH: { my ( $stdout, $stderr ) = run_ack_with_stderr('--ignore-dir=firstlinematch:perl', '--noenv', '-l', 'apple', 't/swamp'); is(scalar(@{$stdout}), 0, '--ignore-dir=firstlinematch:perl is erroneous and should print nothing to standard output'); isnt(scalar(@{$stderr}), 0, '--ignore-dir=firstlinematch:perl is erroneous and should print something to standard error'); like($stderr->[0], qr/Invalid filter specification "firstlinematch" for option '--ignore-dir'/, '--ignore-dir=firstlinematch:perl should report an error message'); } IGNORE_DIR_MATCH_NOIGNORE_DIR: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=match:/\w_subdir/', '--noignore-dir=CVS' ], [ 'RCS', 'another_subdir(?!/CVS)', ], ); sets_match( \@results, \@expected, $test_description ); } IGNORE_DIR_MATCH_NOIGNORE_DIR_IS: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=match:/\w_subdir/', '--noignore-dir=is:CVS' ], [ 'RCS', 'another_subdir(?!/CVS)', ], ); sets_match( \@results, \@expected, $test_description ); } IGNORE_DIR_MATCH_NOIGNORE_DIR_MATCH: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--ignore-dir=match:/\w_subdir/', '--noignore-dir=match:/^..S/' ], [ 'another_subdir(?!/(?:CVS|RCS))', ], ); sets_match( \@results, \@expected, $test_description ); } NOIGNORE_DIR_RELATIVE_PATHS: { set_up_assertion_that_these_options_will_ignore_those_directories( [ '--noignore-dir=' . File::Spec->catdir('t' ,'swamp', 'groceries' , 'another_subdir', 'CVS'), ], [ 'RCS', '(? 10; use lib 't'; use Util; my @expected_norecurse = line_split( <<'END' ); t/swamp/groceries/fruit:1:apple t/swamp/groceries/junk:1:apple fritters END my @expected_recurse = line_split( <<'END' ); t/swamp/groceries/another_subdir/fruit:1:apple t/swamp/groceries/another_subdir/junk:1:apple fritters t/swamp/groceries/dir.d/fruit:1:apple t/swamp/groceries/dir.d/junk:1:apple fritters t/swamp/groceries/fruit:1:apple t/swamp/groceries/junk:1:apple fritters t/swamp/groceries/subdir/fruit:1:apple t/swamp/groceries/subdir/junk:1:apple fritters END if ( is_windows() ) { s{/}{\\}g for ( @expected_norecurse, @expected_recurse ); } my @args; my @lines; prep_environment(); # We sort to ensure deterministic results. @args = qw( -n --sort-files apple t/swamp/groceries ); @lines = run_ack(@args); lists_match( \@lines, \@expected_norecurse, '-n should disable recursion' ); @args = qw( --no-recurse --sort-files apple t/swamp/groceries ); @lines = run_ack(@args); lists_match( \@lines, \@expected_norecurse, '--no-recurse should disable recursion' ); # Make sure that re-enabling recursion works. @args = qw( -n -r --sort-files apple t/swamp/groceries ); @lines = run_ack(@args); lists_match( \@lines, \@expected_recurse, '-r after -n should re-enable recursion' ); @args = qw( --no-recurse -R --sort-files apple t/swamp/groceries ); @lines = run_ack(@args); lists_match( \@lines, \@expected_recurse, '-R after --no-recurse should re-enable recursion' ); @args = qw( --no-recurse --recurse --sort-files apple t/swamp/groceries ); @lines = run_ack(@args); lists_match( \@lines, \@expected_recurse, '--recurse after --no-recurse should re-enable recursion' ); done_testing(); exit 0; ack-v3.5.0/t/invalid-ackrc.t0000644000175100017510000000446214023027176014264 0ustar andyandy#!perl use strict; use warnings; use File::Temp; use List::Util qw( sum ); use Test::More; use lib 't'; use Util; my %types = ( perl => [qw{.pl .pod .pl .t}], python => [qw{.py}], ruby => [qw{.rb Rakefile}], ); plan tests => 3; prep_environment(); my $wd = getcwd_clean(); my $tempdir = File::Temp->newdir; safe_chdir( $tempdir->dirname ); write_file( '.ackrc', "--frobnicate\n" ); subtest 'Check --env and weird options' => sub { plan tests => 10; my $output = run_ack( '--env', '--help' ); like( $output, qr/Usage: ack/ ); $output = run_ack( '--env', '--thpppt' ); like( $output, qr/ack --thpppt/ ); $output = run_ack( '--env', '--bar' ); like( $output, qr/It's a grep/ ); $output = run_ack( '--env', '--cathy' ); like( $output, qr/CHOCOLATE/ ); $output = run_ack( '--env', '--version' ); like( $output, qr/ack v3\.\d+\.\d+/ ); }; subtest 'Check for all the types' => sub { plan tests => 2 + (scalar keys %types) + (sum map { scalar @{$_} } values %types); ( my $output, my $stderr ) = run_ack_with_stderr( '--env', '--help-types' ); # We use "scalar grep" here instead of List::Util::any because any isn't in every version of List::Util. ok( (scalar grep { /Usage: ack/ } @{$output}), 'Found at least one usage line' ); ok( (scalar grep { /Unknown option: frobnicate/ } @{$stderr}), 'Found the illegal option in the ackrc' ); while ( my ($type,$checks) = each %types ) { my ( $matching_line ) = grep { /^\s+$type/ } @{$output}; ok( $matching_line, "Got at least one for --$type" ); foreach my $check (@{$checks}) { like( $matching_line, qr/\Q$check\E/ ); } } }; subtest 'Check --env --man' => sub { plan tests => 2; my ($output, $stderr) = run_ack_with_stderr( '--env', '--man' ); my $filtered_stderr = filter_out_perldoc_noise( $stderr ); is( scalar @{$filtered_stderr}, 0, 'Should have no output to stderr: ack --env --man' ) or diag( join( "\n", 'STDERR:', @{$filtered_stderr} ) ); my $first_two_lines = join( "\n", @{$output}[0,1] ); $first_two_lines =~ s/(.)\cH\1/$1/g; # Eliminate the overstrike used by Pod::Perldoc::ToTextOverstrike like( $first_two_lines, qr/NAME.+ack(?:-standalone)?\s/sm ); }; safe_chdir( $wd ); exit 0; ack-v3.5.0/t/ack-proximate.t0000644000175100017510000001447714023027176014330 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 6; use lib 't'; use Util; prep_environment(); my $const = reslash( 't/text/constitution.txt' ); my $bill = reslash( 't/text/bill-of-rights.txt' ); subtest 'Grouped proximate' => sub { plan tests => 2; my @expected = line_split( <<"HERE" ); $bill 53:fact tried by a jury, shall be otherwise re-examined in any Court of $const 199:To constitute Tribunals inferior to the supreme Court; 372:Judges of the supreme Court, and all other Officers of the United States, 376:in the Courts of Law, or in the Heads of Departments. 404:Court, and in such inferior Courts as the Congress may from time to 406:Courts, shall hold their Offices during good Behaviour, and shall, at 425:and those in which a State shall be Party, the supreme Court shall 427:the supreme Court shall have appellate Jurisdiction, both as to Law and 441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( -p -i --group --sort court ); for my $arg ( qw( --proximate -p ) ) { $args[0] = $arg; ack_lists_match( [ @args, @files ], \@expected, 'Grouped proximate' ); } }; subtest 'Ungrouped proximate' => sub { plan tests => 2; my @expected = line_split( <<"HERE" ); $bill:53:fact tried by a jury, shall be otherwise re-examined in any Court of $const:199:To constitute Tribunals inferior to the supreme Court; $const:372:Judges of the supreme Court, and all other Officers of the United States, $const:376:in the Courts of Law, or in the Heads of Departments. $const:404:Court, and in such inferior Courts as the Congress may from time to $const:406:Courts, shall hold their Offices during good Behaviour, and shall, at $const:425:and those in which a State shall be Party, the supreme Court shall $const:427:the supreme Court shall have appellate Jurisdiction, both as to Law and $const:441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( --proximate -i --nogroup --sort court ); for my $arg ( qw( --proximate -p ) ) { $args[0] = $arg; ack_lists_match( [ @args, @files ], \@expected, 'Ungrouped proximate' ); } }; subtest 'Grouped proximate=2' => sub { plan tests => 2; my @expected = line_split( <<"HERE" ); $bill 53:fact tried by a jury, shall be otherwise re-examined in any Court of $const 199:To constitute Tribunals inferior to the supreme Court; 372:Judges of the supreme Court, and all other Officers of the United States, 376:in the Courts of Law, or in the Heads of Departments. 404:Court, and in such inferior Courts as the Congress may from time to 406:Courts, shall hold their Offices during good Behaviour, and shall, at 425:and those in which a State shall be Party, the supreme Court shall 427:the supreme Court shall have appellate Jurisdiction, both as to Law and 441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( --proximate=2 --group -i --sort court ); for my $arg ( qw( --proximate=2 -p2 ) ) { $args[0] = $arg; ack_lists_match( [ @args, @files ], \@expected, 'Grouped proximate=2' ); } }; subtest 'Ungrouped proximate=2' => sub { plan tests => 2; my @expected = line_split( <<"HERE" ); $bill:53:fact tried by a jury, shall be otherwise re-examined in any Court of $const:199:To constitute Tribunals inferior to the supreme Court; $const:372:Judges of the supreme Court, and all other Officers of the United States, $const:376:in the Courts of Law, or in the Heads of Departments. $const:404:Court, and in such inferior Courts as the Congress may from time to $const:406:Courts, shall hold their Offices during good Behaviour, and shall, at $const:425:and those in which a State shall be Party, the supreme Court shall $const:427:the supreme Court shall have appellate Jurisdiction, both as to Law and $const:441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( --proximate=2 --nogroup -i --sort court ); for my $arg ( qw( --proximate=2 -p2 ) ) { $args[0] = $arg; ack_lists_match( [ @args, @files ], \@expected, 'Ungrouped proximate=2' ); } }; subtest 'Ungrouped proximate=20' => sub { plan tests => 2; my @expected = line_split( <<"HERE" ); $bill:53:fact tried by a jury, shall be otherwise re-examined in any Court of $const:199:To constitute Tribunals inferior to the supreme Court; $const:372:Judges of the supreme Court, and all other Officers of the United States, $const:376:in the Courts of Law, or in the Heads of Departments. $const:404:Court, and in such inferior Courts as the Congress may from time to $const:406:Courts, shall hold their Offices during good Behaviour, and shall, at $const:425:and those in which a State shall be Party, the supreme Court shall $const:427:the supreme Court shall have appellate Jurisdiction, both as to Law and $const:441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( --proximate=20 --nogroup -i --sort court ); for my $arg ( qw( --proximate=20 -p20 ) ) { $args[0] = $arg; ack_lists_match( [ @args, @files ], \@expected, 'Ungrouped proximate=20' ); } }; subtest '-P overrides --prox' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill:53:fact tried by a jury, shall be otherwise re-examined in any Court of $const:199:To constitute Tribunals inferior to the supreme Court; $const:372:Judges of the supreme Court, and all other Officers of the United States, $const:376:in the Courts of Law, or in the Heads of Departments. $const:404:Court, and in such inferior Courts as the Congress may from time to $const:406:Courts, shall hold their Offices during good Behaviour, and shall, at $const:425:and those in which a State shall be Party, the supreme Court shall $const:427:the supreme Court shall have appellate Jurisdiction, both as to Law and $const:441:of two Witnesses to the same overt Act, or on Confession in open Court. HERE my @files = qw( t/text ); my @args = qw( --proximate=20 --nogroup -i --sort -P court ); ack_lists_match( [ @args, @files ], \@expected, '-P overrides --prox' ); }; done_testing(); exit 0; ack-v3.5.0/t/line-endings.t0000644000175100017510000000452314023027176014127 0ustar andyandy#!perl =pod This test checks for problems where line endings aren't handled correctly by our pre-scanning of the file. # https://github.com/beyondgrep/ack2/issues/491 v2.14 with "-l" not emitting all matching files. > echo ' ' >space-newline.txt > echo $' \n' >space-newline-newline.txt > ack ' $' space-newline*.txt space-newline-newline.txt 1: space-newline.txt 1: > ack -l ' $' space-newline*.txt space-newline.txt =cut use strict; use warnings; use lib 't'; use Test::More tests => 4; use File::Temp; use Util; prep_environment(); my $dir = File::Temp->newdir; my $wd = getcwd_clean(); safe_chdir( $dir->dirname ); my %matching_files = ( 'space-newline.txt' => " \n", 'space-newline-space.txt' => " \n\t", 'space-newline-newline.txt' => " \n\n", 'space-newline-and-more.txt' => "this\n \nthat\n", 'words-and-spaces.txt' => "this \nand that\n", ); my %nonmatching_files = ( 'tabby.txt' => "\t\n", 'also-tabby.txt' => " \t\n", ); my %all_files = ( %matching_files, %nonmatching_files ); while ( my ($file,$content) = each %all_files ) { write_file( $file, $content ); } my @all_files = keys %all_files; my @matching_files = keys %matching_files; my @nonmatching_files = keys %nonmatching_files; subtest 'Match normally' => sub { plan tests => 2; my @results = run_ack( ' $', @all_files ); my @files_matched = @results; s/:.*// for @files_matched; sets_match( \@files_matched, [ @matching_files ], 'Found all the matching files in results' ); }; subtest 'Match with -l' => sub { plan tests => 2; my @results = run_ack( '-l', ' $', @all_files ); sets_match( \@results, [ @matching_files ], 'Matching files should be in -l output' ); }; subtest 'Non-match with -L' => sub { plan tests => 2; my @results = run_ack( '-L', ' $', @all_files ); sets_match( \@results, [ @nonmatching_files ], 'Nonmatching files should be in -L output' ); }; subtest 'Count with -c' => sub { plan tests => 2; my @results = run_ack( '-c', ' $', @all_files ); sets_match( \@results, [ map { "$_:" . ( $matching_files{$_} ? 1 : 0 ) } @all_files ], 'Matching files should be in -c output with correct counts' ); }; safe_chdir( $wd ); # Get out of temp directory so it can be cleaned up. done_testing(); exit 0; ack-v3.5.0/t/ack-x.t0000644000175100017510000000734614023027176012564 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 2; use lib 't'; use Util; prep_environment(); my $ozy__ = reslash( 't/text/ozymandias.txt' ); my $raven = reslash( 't/text/raven.txt' ); my @expected = line_split( <<"HERE" ); $ozy__:6:Tell that its sculptor well those passions read $ozy__:8:The hand that mocked them, and the heart that fed: $ozy__:13:Of that colossal wreck, boundless and bare $raven:17:So that now, to still the beating of my heart, I stood repeating $raven:26:That I scarce was sure I heard you" -- here I opened wide the door: -- $raven:29:Deep into that darkness peering, long I stood there wondering, fearing, $raven:38:"Surely," said I, "surely that is something at my window lattice; $raven:59:For we cannot help agreeing that no living human being $raven:65:That one word, as if his soul in that one word he did outpour. $raven:75:Till the dirges of his Hope that melancholy burden bore $raven:88:On the cushion's velvet lining that the lamplight gloated o'er, $raven:107:By that Heaven that bends above us, by that God we both adore, $raven:113:"Be that word our sign of parting, bird or fiend!" I shrieked, upstarting: $raven:115:Leave no black plume as a token of that lie thy soul hath spoken! $raven:122:And his eyes have all the seeming of a demon's that is dreaming, $raven:124:And my soul from out that shadow that lies floating on the floor HERE subtest 'Basics' => sub { plan tests => 2; my @lhs_args = adjust_executable( build_ack_invocation( '--sort-files', '-g', '[vz]', 't/text' ) ); my @rhs_args = adjust_executable( build_ack_invocation( '-x', '-i', 'that' ) ); my ($stdout, $stderr); if ( is_windows() ) { ($stdout, $stderr) = run_cmd("@lhs_args | @rhs_args"); } else { ($stdout, $stderr) = run_piped( \@lhs_args, \@rhs_args ); } sets_match( $stdout, \@expected, __FILE__ ); is_empty_array( $stderr ); }; # GH #175: -s doesn't work with -x # We have to show that -s supresses errors on missing and unreadable files, # while still giving results on files that are there. subtest 'GH #175' => sub { plan skip_all => q{Can't be run as root} if $> == 0; plan tests => 5; my @search_files; my @expected_errors; my $unreadable_file; # Can't be localized or else it will be cleaned up. my $nonexistent_filename = '/tmp/non-existent-file' . $$ . '.txt'; push( @search_files, $nonexistent_filename ); push( @expected_errors, qr/\Q$nonexistent_filename: No such file/ ); if ( !is_windows() ) { $unreadable_file = create_tempfile(); my $unreadable_filename = $unreadable_file->filename; my (undef, $result) = make_unreadable( $unreadable_filename ); die $result if $result; push( @search_files, $unreadable_filename ); push( @expected_errors, qr/\Q$unreadable_filename: Permission denied/ ); } my $ok_file = create_tempfile( 'My Pal Foot-Foot', 'Foo Fighters', 'I pity the fool', 'Not a match' ); push( @search_files, $ok_file ); my $input_file = create_tempfile( @search_files ); # Without -s, we get an error about the missing file. my ($stdout,$stderr) = pipe_into_ack_with_stderr( $input_file->filename, '-x', '-i', 'foo' ); is( scalar @{$stdout}, 3, 'Got three matches' ); my $n = 0; for my $error ( @{$stderr} ) { ++$n; my $expected = shift @expected_errors; like( $error, $expected, "Error #$n matches" ); } pass( 'One freebie pass for Windows' ) if is_windows(); # With -s, there is no warning. ($stdout,$stderr) = pipe_into_ack_with_stderr( $input_file->filename, '-x', '-i', '-s', 'foo' ); is( scalar @{$stdout}, 3, 'Still got three matches' ); is_empty_array( $stderr, 'No errors' ); }; done_testing(); exit 0; ack-v3.5.0/t/zero.t0000644000175100017510000000173314023027176012532 0ustar andyandy#!perl =pod Long ago there was a problem where ack would ignore a file named "0" because 0 is a false value in Perl. Here we check to make sure we don't fall prey to that again. =cut use warnings; use strict; use Test::More tests => 2; use lib 't'; use Util; prep_environment(); my $swamp = 't/swamp'; my @actual_swamp_perl = map { "$swamp/$_" } qw( 0 constitution-100k.pl Makefile.PL options.pl options-crlf.pl perl.cgi perl.handler.pod perl.pl perl.pm perl.pod perl-test.t perl-without-extension ); DASH_F: { my @args = qw( -f -t perl ); ack_sets_match( [ @args, $swamp ], \@actual_swamp_perl, 'DASH_F' ); } DASH_F_CWD: { my @args = qw( -f -t perl --sort-files ); my @swamp_basenames = @actual_swamp_perl; s{^$swamp/}{} for @swamp_basenames; my $wd = getcwd_clean(); safe_chdir('t/swamp'); ack_sets_match( [ @args, '.' ], \@swamp_basenames, 'DASH_F_CWD:' ); safe_chdir($wd); } exit 0; ack-v3.5.0/t/ack-man.t0000644000175100017510000000133514023027176013060 0ustar andyandy#!perl use strict; use warnings; use 5.010001; use lib 't'; use Util; use Test::More; plan tests => 2; prep_environment(); my ($stdout, $stderr) = run_ack_with_stderr( '--man' ); my @lines = @{$stdout}; my $nlines = scalar @lines; my $ok = ($nlines > 900) && ($nlines < 2000); diag $nlines; if ( !ok( $ok, "Manual should be between 900-2000 lines long but is actually $nlines long" ) ) { my @first = grep { defined } @lines[0..19]; diag( '--man start=', explain( \@first ) ); my @last = grep { defined } @lines[-20..-1]; diag( '--man end=', explain( \@last ) ); } my $filtered_stderr = filter_out_perldoc_noise( $stderr ); is_empty_array( $filtered_stderr, 'Nothing in STDERR' ); done_testing(); exit 0; ack-v3.5.0/t/ack-i.barfly0000644000175100017510000000176614023027176013561 0ustar andyandyBEGIN No -i, or -I RUN ack foo ack -I foo ack --no-smart-case foo YES football foo bar NO Football foOtball END BEGIN Normal -i RUN ack -i foo ack -i Foo ack --ignore-case foo ack --ignore-case Foo YES football foo bar Football foOtball NO END BEGIN --smart-case invoked RUN ack --smart-case foo ack -S foo YES football foo bar Football foOtball NO END BEGIN --smart-case bypassed RUN ack --smart-case Foo ack -S Foo YES Football NO football foo bar foOtball END BEGIN --smart-case overrides -i RUN ack -i --smart-case Foo ack -i -S Foo YES Football NO football foo bar foOtball END BEGIN -i overrides --smart-case RUN ack --smart-case -i Foo ack --smart-case -i foo ack -S -i Foo ack -S -i foo YES Football football foo bar foOtball NO END BEGIN -I overrides -i RUN ack -i -I Foo YES Football NO foOtball football foo bar END BEGIN -I overrides --smart-case RUN ack --smart-case -I Foo ack -S -I Foo YES Football NO football foo bar foOtball END # vi:set ft=barfly: ack-v3.5.0/t/incomplete-last-line.t0000644000175100017510000000225114023027176015574 0ustar andyandy#!perl use warnings; use strict; use Test::More tests => 4; use lib 't'; use Util; prep_environment(); # Check that a match on the last line of a file without a proper # ending newline gets this newline appended by ack. VERIFY_LAST_LINE_IS_MISSING_NEWLINE: { # Verify that our test data file is set up the way we expect and that it hasn't had a newline # added to the end of the file by mistake. open( my $fh, '<', 't/swamp/incomplete-last-line.txt' ) or die $!; my @lines = <$fh>; close $fh; is( substr( $lines[0], -1, 1 ), "\n", 'First line ends with a newline' ); is( substr( $lines[1], -1, 1 ), "\n", 'Second line ends with a newline' ); is( substr( $lines[2], -1, 1 ), '!', 'Third line ends with a bang, not a newline' ); } INCOMPLETE_LAST_LINE: { my @expected = line_split( <<'HERE' ); but no new line on the last line! the last full measure of devotion -- that we here highly resolve that HERE my @args = qw( -h --nogroup last ); my @files = qw( t/swamp/incomplete-last-line.txt t/text/gettysburg.txt ); ack_lists_match( [ @args, @files ], \@expected, 'Incomplete line gets a newline appended.' ); } done_testing(); exit 0; ack-v3.5.0/t/basic.t0000644000175100017510000000432714023027176012636 0ustar andyandy#!perl use strict; use warnings; use lib 't'; use Util; use Test::More tests => 14; prep_environment(); NO_SWITCHES_ONE_DIRECTORY: { my $target_file = reslash( 't/text/gettysburg.txt' ); my @expected = line_split( <<"HERE" ); $target_file:14:struggled here, have consecrated it, far above our poor power to add or HERE my @files = qw( t/text ); my @args = qw( consecrated ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for strict in one directory' ); } NO_SWITCHES_ONE_FILE: { my @expected = line_split( <<'HERE' ); use strict; HERE my @files = qw( t/swamp/options.pl ); my @args = qw( strict ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for strict in one file' ); } NO_SWITCHES_MULTIPLE_FILES: { my $options_file = reslash( 't/swamp/options.pl' ); my $const___file = reslash( 't/text/constitution.txt' ); my @expected = line_split( <<"HERE" ); $const___file:225:such District (not exceeding ten Miles square) as may, by Cession of $options_file:2:use strict; HERE my @files = qw( t/text/constitution.txt t/swamp/pipe-stress-freaks.F t/swamp/options.pl ); my @args = qw( strict ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for strict in multiple files' ); } WITH_SWITCHES_ONE_FILE: { my $target_file = reslash( 't/swamp/options.pl' ); for my $opt ( qw( -H --with-filename ) ) { my @expected = line_split( <<"HERE" ); $target_file:2:use strict; HERE my @files = qw( t/swamp/options.pl ); my @args = ( $opt, qw( strict ) ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, "Looking for strict in one file with $opt" ); } } WITH_SWITCHES_MULTIPLE_FILES: { for my $opt ( qw( -h --no-filename ) ) { my @expected = line_split( <<"HERE" ); use strict; HERE my @files = qw( t/swamp/options.pl t/swamp/crystallography-weenies.f ); my @args = ( $opt, qw( strict ) ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, "Looking for strict in multiple files with $opt" ); } } done_testing(); exit 0; ack-v3.5.0/t/ack-help.t0000644000175100017510000000266614023027176013245 0ustar andyandy#!perl use strict; use warnings; use Test::More; use lib 't'; use Util; { my $help_options; sub _populate_help_options { my ( $output, undef ) = run_ack_with_stderr( '--help' ); $help_options = []; foreach my $line (@{$output}) { if ( $line =~ /^\s+-/ ) { while ( $line =~ /(-[^\s=,]+)/g ) { my $option = $1; chop $option if $option =~ /\[$/; if ( $option =~ s/^--\[no\]/--/ ) { my $negated_option = $option; substr $negated_option, 2, 0, 'no'; push @{$help_options}, $negated_option; } push @{$help_options}, $option; } } } return; } sub get_help_options { _populate_help_options() unless $help_options; return @{ $help_options }; } } sub option_in_usage { my ( $expected_option ) = @_; my @help_options = get_help_options(); my $found; foreach my $option ( @help_options ) { if ( $option eq $expected_option ) { $found = 1; last; } } ok( $found, "Option '$expected_option' found in --help output" ); return; } my @options = get_expected_options(); plan tests => scalar(@options); prep_environment(); foreach my $option ( @options ) { option_in_usage( $option ); } ack-v3.5.0/t/range/0000755000175100017510000000000014023040526012450 5ustar andyandyack-v3.5.0/t/range/america-the-beautiful.html0000644000175100017510000000305714023027176017506 0ustar andyandy America the Beautiful

America the Beautiful

O beautiful for spacious skies, For amber waves of grain, For purple mountain majesties Above the fruited plain! America! America! God shed His grace on thee And crown thy good with brotherhood From sea to shining sea!
O beautiful for pilgrim feet, Whose stern, impassioned stress A thoroughfare for freedom beat Across the wilderness! America! America! God mend thine every flaw, Confirm thy soul in self-control, Thy liberty in law!
O beautiful for heroes proved In liberating strife, Who more than self their country loved And mercy more than life! America! America! May God thy gold refine, Till all success be nobleness, And every gain divine!
O beautiful for patriot dream That sees beyond the years Thine alabaster cities gleam Undimmed by human tears! America! America! God shed His grace on thee And crown thy good with brotherhood From sea to shining sea!
ack-v3.5.0/t/range/stars-and-stripes-forever.html0000644000175100017510000000414414023027176020400 0ustar andyandy The Stars and Stripes Forever

The Stars and Stripes Forever

By John Philip Sousa

Let martial note in triumph float And liberty extend its mighty hand A flag appears 'mid thunderous cheers, The banner of the Western land. The emblem of the brave and true Its folds protect no tyrant crew; The red and white and starry blue Is freedom's shield and hope. Let eagle shriek from lofty peak The never-ending watchword of our land; Let summer breeze waft through the trees The echo of the chorus grand. Sing out for liberty and light, Sing out for freedom and the right. Sing out for Union and its might, O patriotic sons.
Other nations may deem their flags the best And cheer them with fervid elation But the flag of the North and South and West Is the flag of flags, the flag of Freedom's nation.
Hurrah for the flag of the free! May it wave as our standard forever, The gem of the land and the sea, The banner of the right. Let despots remember the day When our fathers with mighty endeavor Proclaimed as they marched to the fray That by their might and by their right It waves forever.
Hurrah for the flag of the free. May it wave as our standard forever The gem of the land and the sea, The banner of the right. Let despots remember the day When our fathers with mighty endeavor Proclaimed as they marched to the fray, That by their might and by their right It waves forever.
ack-v3.5.0/t/range/johnny-rebeck.txt0000644000175100017510000000133014023027176015752 0ustar andyandyVERSE There once was a little Dutchman His name was Johnny Rebeck He was a dealer in sauerkraut And sausages and speck He was the finest Dutchman The best you've ever seen 'til one day he invented A great big sausage machine Bang! CHORUS Oh, Mr. Johnny Rebeck what makes you be so mean? I told you you'd be sorry for inventing that machine Now all the neighbors' cats and dogs will nevermore be seen They'll all be ground to sausages in Johnny Rebeck's machine. Bang! VERSE One night the darn thing busted The darn thing wouldn't go So Johnny Rebeck crawled inside To see what made it so That night his wife had a nightmare And walking in her sleep She turned the crank And gave it a yank Pooooor Johnny Rebeck was meat Bang! ack-v3.5.0/t/range/anchors-aweigh.html0000644000175100017510000000204314023027176016242 0ustar andyandy Anchors Aweigh>

Anchors Aweigh

Stand Navy out to sea, fight our battle cry! We'll never change our course so vicious foes steer shy-y-y-y! Roll out the TNT, anchors aweigh! Sail on to victory, and sink their bones to Davy Jones, hooray!
Anchors Aweigh, my boys, Anchors Aweigh! Farewell to foreign Shores, we sail at break of day-ay-ay-ay; Through our last night ashore, drink to the foam, Until we meet once more, here's wishing you a happy voyage home!
Blue of the mighty deep, Gold of God's great sun; Let these our colors be, Till All of time be done-n-n-ne; On seven seas we learn, Navy's stern call: Faith, courage, service true, With honor over, honor over all.
ack-v3.5.0/t/range/rangefile.pm0000644000175100017510000000044014023027176014746 0ustar andyandypackage RangeFile; # For testing the range function. use warnings; use strict; use 5.010; # This function calls print on "foo". sub foo { print 'foo'; return 1; } my $print = 1; my $update = 5; sub bar { print 'bar'; return 2; } my $task = 'print'; $update = 12; 1; ack-v3.5.0/t/00-load.t0000644000175100017510000000271614023027176012711 0ustar andyandy#!perl use 5.010; use warnings; use strict; use Test::More tests => 20; # Load all these modules to get their versions. use App::Ack; use File::Next; use File::Spec; use Getopt::Long; use Pod::Perldoc; use Pod::Text; use Pod::Usage; use Term::ANSIColor; use Test::Harness; my @modules = qw( File::Next File::Spec Getopt::Long Pod::Perldoc Pod::Text Pod::Usage Term::ANSIColor Test::Harness Test::More ); pass( 'All external modules loaded' ); diag sprintf( 'Testing ack %s under Perl v%vd, %s', $App::Ack::VERSION, $^V, $^X ); for my $module ( @modules ) { no strict 'refs'; my $ver = ${$module . '::VERSION'}; diag( "Using $module $ver" ); } diag( 'PATH=' . ($ENV{PATH} // '') ); # Find all the .pm files in blib/ and make sure they can be Cd. my $iter = File::Next::files( { file_filter => sub { /\.pm$/ } }, 'blib' ); while ( my $file = $iter->() ) { $file =~ s/\.pm$// or die "There should be a .pm at the end of $file but there isn't"; my @dirs = File::Spec->splitdir( $file ); # Break apart the path, throw away blib/lib/, and reconstitute the module name. my $junk = shift @dirs; die unless $junk eq 'blib'; $junk = shift @dirs; die unless $junk eq 'lib'; my $module = join( '::', @dirs ); $module =~ /^([a-z::]+)$/i or die "Invalid module name $module"; $module = $1; # Untainted my $rc = eval "use $module; 1;"; ok( $rc, "use $module" ); } done_testing(); ack-v3.5.0/t/ack-type.t0000644000175100017510000001044314023027176013266 0ustar andyandy#!perl use strict; use warnings; use Test::More tests => 26; use lib 't'; use Util; prep_environment(); my @SWAMP = qw( t/swamp ); TEST_TYPE: { my @expected = line_split( <<'HERE' ); t/swamp/0:1:#!/usr/bin/perl -w t/swamp/Makefile.PL:1:#!perl t/swamp/options-crlf.pl:1:#!/usr/bin/env perl t/swamp/options.pl:1:#!/usr/bin/env perl t/swamp/perl-test.t:1:#!perl t/swamp/perl-without-extension:1:#!/usr/bin/perl -w t/swamp/perl.cgi:1:#!perl t/swamp/perl.pl:1:#!perl t/swamp/perl.pm:1:#!perl HERE # Reslash the filenames in case we are on Windows. foreach ( @expected ) { s/^(.*?)(?=:)/reslash( $1 )/ge; } my @args = qw( --type=perl --nogroup --noheading --nocolor ); my @files = @SWAMP; my $target = 'perl'; my @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_TYPE with --type=perl' ); # Try it again with -t. @args = qw( -t perl --nogroup --noheading --nocolor ); @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_TYPE with -t perl' ); # Try it again with --perl. @args = qw( --perl --nogroup --noheading --nocolor ); @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_TYPE with --perl' ); } TEST_NOTYPE: { my @expected = line_split( <<'HERE' ); t/swamp/c-header.h:1:/* perl.h t/swamp/Makefile:1:# This Makefile is for the ack extension to perl. HERE # Reslash the filenames in case we are on Windows. for ( @expected ) { s/^(.*?)(?=:)/reslash( $1 )/ge; } my @args = qw( --type=noperl --nogroup --noheading --nocolor ); my @files = @SWAMP; my $target = 'perl'; my @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_NOTYPE with --type' ); # Try as --noperl @args = qw( --noperl --nogroup --noheading --nocolor ); @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_NOTYPE with --noperl' ); # Try as -t noperl @args = qw( -t noperl --nogroup --noheading --nocolor ); @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_NOTYPE with -t noperl' ); # Try it with -T. @args = qw( -T perl --nogroup --noheading --nocolor ); @results = run_ack( @args, $target, @files ); sets_match( \@results, \@expected, 'TEST_NOTYPE with -T' ); } TEST_UNKNOWN_TYPE: { my @args = qw( --ignore-ack-defaults --type-add=perl:ext:pl --type=foo --nogroup --noheading --nocolor ); my @files = @SWAMP; my $target = 'perl'; my ( $stdout, $stderr ) = run_ack_with_stderr( @args, $target, @files ); is_empty_array( $stdout, 'Should have no lines back' ); first_line_like( $stderr, qr/Unknown type 'foo'/ ); } TEST_NOTYPES: { my @args = qw( --ignore-ack-defaults --type=perl --nogroup --noheading --nocolor ); my @files = @SWAMP; my $target = 'perl'; my ( $stdout, $stderr ) = run_ack_with_stderr( @args, $target, @files ); is_empty_array( $stdout, 'Should have no lines back' ); first_line_like( $stderr, qr/Unknown type 'perl'/ ); } TEST_NOTYPE_OVERRIDE: { my @expected = ( reslash('t/swamp/html.htm') . ':2:Boring test file ', reslash('t/swamp/html.html') . ':2:Boring test file ', ); my @lines = run_ack( '--nohtml', '--html', '--sort-files', '', @SWAMP ); is_deeply( \@lines, \@expected ); } TEST_TYPE_OVERRIDE: { my @lines = run_ack( '--html', '--nohtml', '<title>', @SWAMP ); is_empty_array( \@lines ); } TEST_NOTYPE_ACKRC_CMD_LINE_OVERRIDE: { my $ackrc = <<'HERE'; --nohtml HERE my @expected = ( reslash('t/swamp/html.htm') . ':2:<html><head><title>Boring test file ', reslash('t/swamp/html.html') . ':2:Boring test file ', ); my @lines = run_ack('--html', '--sort-files', '', @SWAMP, { ackrc => \$ackrc, }); is_deeply( \@lines, \@expected ); } TEST_TYPE_ACKRC_CMD_LINE_OVERRIDE: { my $ackrc = <<'HERE'; --html HERE my @expected; my @lines = run_ack('--nohtml', '<title>', @SWAMP, { ackrc => \$ackrc, }); is_deeply( \@lines, \@expected ); } done_testing(); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-pager.t����������������������������������������������������������������������������0000644�0001751�0001751�00000014264�14023027176�013410� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; use lib 't'; use Util; if ( not has_io_pty() ) { plan skip_all => q{You need to install IO::Pty to run this test}; exit(0); } plan tests => 9; prep_environment(); NO_PAGER: { my @args = qw(--nocolor --sort-files -i nevermore t/text); my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'NO_PAGER' ); } PAGER: { my @args = qw(--nocolor --pager=t/test-pager --sort-files -i nevermore t/text); my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'PAGER' ); } PAGER_WITH_OPTS: { my @args = ( '--nocolor', '--pager=t/test-pager --skip=2', # --skip is an argument passed to test-pager '--sort-files', '-i', 'nevermore', 't/text', ); my @expected = line_split( <<'HERE' ); t/text/raven.txt 62: With such name as "Nevermore." 76: Of 'Never -- nevermore.' 90: She shall press, ah, nevermore! 104: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'PAGER_WITH_OPTS' ); } FORCE_NO_PAGER: { my @args = ( '--nocolor', '--pager=t/test-pager --skip=2', # --skip is an argument passed to test-pager '--nopager', '--sort-files', '-i', 'nevermore', 't/text', ); my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'FORCE_NO_PAGER' ); } PAGER_ENV: { local $ENV{'ACK_PAGER'} = 't/test-pager --skip=2'; local $TODO = q{Setting ACK_PAGER in tests won't work for the time being}; my @args = qw( --nocolor --sort-files -i nevermore t/text ); my @expected = line_split( <<'HERE' ); t/text/raven.txt 62: With such name as "Nevermore." 76: Of 'Never -- nevermore.' 90: She shall press, ah, nevermore! 104: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'PAGER_ENV' ); } PAGER_ENV_OVERRIDE: { local $ENV{'ACK_PAGER'} = 't/test-pager --skip=2'; my @args = qw( --nocolor --nopager --sort-files -i nevermore t/text ); my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'PAGER_ENV_OVERRIDE' ); } PAGER_ACKRC: { my @args = qw( --nocolor --sort-files -i nevermore t/text ); my $ackrc = <<'HERE'; --pager=t/test-pager --skip=2 HERE my @expected = line_split( <<'HERE' ); t/text/raven.txt 62: With such name as "Nevermore." 76: Of 'Never -- nevermore.' 90: She shall press, ah, nevermore! 104: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." HERE my @got = run_ack_interactive(@args, { ackrc => \$ackrc, }); lists_match( \@got, \@expected, 'PAGER_ACKRC' ); } PAGER_ACKRC_OVERRIDE: { my @args = qw( --nocolor --nopager --sort-files -i nevermore t/text ); my $ackrc = <<'HERE'; --pager=t/test-pager --skip=2 HERE my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args, { ackrc => \$ackrc, }); lists_match( \@got, \@expected, 'PAGER_ACKRC_OVERRIDE' ); } PAGER_NOENV: { local $ENV{'ACK_PAGER'} = 't/test-pager --skip=2'; my @args = qw( --nocolor --noenv --sort-files -i nevermore t/text ); my @expected = line_split( <<'HERE' ); t/text/raven.txt 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE my @got = run_ack_interactive(@args); lists_match( \@got, \@expected, 'PAGER_NOENV' ); } done_testing(); exit 0; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-column.t���������������������������������������������������������������������������0000644�0001751�0001751�00000003262�14023027176�013603� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 4; use lib 't'; use Util; prep_environment(); my $raven = reslash( 't/text/raven.txt' ); my @base_args = qw( nevermore -w -i --with-filename --noenv ); WITH_COLUMNS: { my @expected = line_split( <<'HERE' ); 55:23: Quoth the Raven, "Nevermore." 62:24: With such name as "Nevermore." 69:26: Then the bird said, "Nevermore." 76:18: Of 'Never -- nevermore.' 83:24: Meant in croaking "Nevermore." 90:26: She shall press, ah, nevermore! 97:23: Quoth the Raven, "Nevermore." 104:23: Quoth the Raven, "Nevermore." 111:23: Quoth the Raven, "Nevermore." 118:23: Quoth the Raven, "Nevermore." 125:22: Shall be lifted--nevermore! HERE @expected = map { "${raven}:$_" } @expected; my @files = ( $raven ); my @args = ( @base_args, '--column' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Checking column numbers' ); } WITHOUT_COLUMNS: { my @expected = line_split( <<'HERE' ); 55: Quoth the Raven, "Nevermore." 62: With such name as "Nevermore." 69: Then the bird said, "Nevermore." 76: Of 'Never -- nevermore.' 83: Meant in croaking "Nevermore." 90: She shall press, ah, nevermore! 97: Quoth the Raven, "Nevermore." 104: Quoth the Raven, "Nevermore." 111: Quoth the Raven, "Nevermore." 118: Quoth the Raven, "Nevermore." 125: Shall be lifted--nevermore! HERE @expected = map { "${raven}:$_" } @expected; my @files = ( $raven ); my @args = ( @base_args, '--no-column' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Checking without column numbers' ); } done_testing(); exit 0; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-c.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000003536�14023027176�012534� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 6; use lib 't'; use Util; prep_environment(); DASH_C: { my @expected = qw( t/text/amontillado.txt:2 t/text/bill-of-rights.txt:0 t/text/constitution.txt:0 t/text/gettysburg.txt:1 t/text/number.txt:0 t/text/numbered-text.txt:0 t/text/ozymandias.txt:0 t/text/raven.txt:2 ); my @args = qw( God -c --sort-files ); my @files = qw( t/text ); ack_sets_match( [ @args, @files ], \@expected, 'God counts' ); push( @args, '--no-filename' ); ack_sets_match( [ @args, @files ], [ 5 ], 'God counts, total only' ); } WITH_DASH_V: { my @expected = qw( t/text/amontillado.txt:206 t/text/bill-of-rights.txt:45 t/text/constitution.txt:259 t/text/gettysburg.txt:15 t/text/number.txt:1 t/text/numbered-text.txt:20 t/text/ozymandias.txt:9 t/text/raven.txt:77 ); my @args = qw( the -i -w -v -c --sort-files ); my @files = qw( t/text ); ack_sets_match( [ @args, @files ], \@expected, 'Non-the counts' ); } DASH_LC: { my @expected = qw( t/text/bill-of-rights.txt:1 t/text/constitution.txt:29 ); my @args = qw( congress -i -l -c --sort-files ); my @files = qw( t/text ); ack_sets_match( [ @args, @files ], \@expected, 'congress counts with -l -c' ); } DASH_HC: { my @args = qw( Montresor -c -h ); my @files = qw( t/text ); my @expected = ( '3' ); ack_sets_match( [ @args, @files ], \@expected, 'ack -c -h should return one line of results' ); } SINGLE_FILE_COUNT: { my @args = qw( Montresor -c -h ); my @files = ( 't/text/amontillado.txt' ); my @expected = ( '3' ); ack_sets_match( [ @args, @files ], \@expected, 'ack -c -h should return one line of results' ); } exit 0; ������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/inverted-file-filter.t�����������������������������������������������������������������0000644�0001751�0001751�00000004504�14023027176�015572� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't', 't/internals'; use Test::More tests => 4; use Util; prep_environment(); EXCLUDE_ONLY: { my @expected = ( qw( t/swamp/c-header.h t/swamp/c-source.c t/swamp/crystallography-weenies.f t/swamp/example.R t/swamp/file.bar t/swamp/file.foo t/swamp/fresh.css t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/meat t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/meat t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/meat t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/subdir/meat t/swamp/html.htm t/swamp/html.html t/swamp/incomplete-last-line.txt t/swamp/javascript.js t/swamp/lua-shebang-test t/swamp/Makefile t/swamp/MasterPage.master t/swamp/notaMakefile t/swamp/notaRakefile t/swamp/notes.md t/swamp/pipe-stress-freaks.F t/swamp/Rakefile t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.asp t/swamp/sample.aspx t/swamp/sample.rake t/swamp/service.svc t/swamp/stuff.cmake t/swamp/CMakeLists.txt t/swamp/swamp/ignoreme.txt ), 't/swamp/not-an-#emacs-workfile#', ); my @args = qw( -T perl -f t/swamp ); ack_sets_match( [ @args ], \@expected, 'Exclude only' ); # Do it again with -t noperl @args = qw( -t noperl -f t/swamp ); ack_sets_match( [ @args ], \@expected, 'Exclude only' ); # Do it again with --type=noperl @args = qw( -t noperl -f t/swamp ); ack_sets_match( [ @args ], \@expected, 'Exclude only' ); } INCLUDE_PLUS_EXCLUDE_ONLY: { my @expected = qw( t/swamp/0 t/swamp/constitution-100k.pl t/swamp/perl.pm t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/perl-without-extension t/swamp/perl.cgi t/swamp/Makefile.PL t/swamp/perl-test.t t/swamp/perl.pl ); my @args = qw( --type-add=pod:ext:pod -t perl -T pod -f t/swamp ); ack_sets_match( [ @args ], \@expected, 'Include plus exclude only' ); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/test-pager�����������������������������������������������������������������������������0000755�0001751�0001751�00000000322�14023027176�013360� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env perl use strict; use warnings; use Getopt::Long; my $skip; GetOptions( 'skip=i' => \$skip, ); while (<>) { if ( defined $skip && $. % $skip == 0 ) { next; } print; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/invalid-options.t����������������������������������������������������������������������0000644�0001751�0001751�00000001135�14023027176�014666� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # https://github.com/beyondgrep/ack3/issues/192 use strict; use warnings; use Test::More tests => 5; use lib 't'; use Util; prep_environment(); my ( $stdout, $stderr ) = run_ack_with_stderr( '--bloofga' ); is_empty_array( $stdout, 'No output because of our bad option' ); is( $stderr->[0], 'Unknown option: bloofga', 'First line is the error, and should only appear once' ); like( $stderr->[1], qr/ack(?:-standalone)?: Invalid option on command line/, 'Second line is the general error' ); is( scalar @{$stderr}, 2, 'There are no more lines' ); is( get_rc(), 255, 'Should fail' ); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/empty-lines.t��������������������������������������������������������������������������0000644�0001751�0001751�00000000561�14023027176�014017� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # https://github.com/beyondgrep/ack2/issues/562 use strict; use warnings; use lib 't'; use Test::More tests => 2; use Util; prep_environment(); my $tempfile = create_tempfile( ('') x 3 ); my @results = run_ack('^\s\s+$', $tempfile->filename); is_empty_array( \@results, '^\s\s+$ should never match a sequence of empty lines' ); done_testing(); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-h.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000003210�14023027176�012526� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More tests => 12; use lib 't'; use Util; prep_environment(); NO_SWITCHES_ONE_FILE: { my @expected = line_split( <<'HERE' ); use strict; HERE my @files = qw( t/swamp/options.pl ); my @args = qw( strict ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for strict in one file' ); } NO_SWITCHES_MULTIPLE_FILES: { my $target_file = reslash( 't/swamp/options.pl' ); my @expected = line_split( <<"HERE" ); $target_file:2:use strict; HERE my @files = qw( t/swamp/options.pl t/swamp/pipe-stress-freaks.F ); my @args = qw( strict ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for strict in multiple files' ); } WITH_SWITCHES_ONE_FILE: { my $target_file = reslash( 't/swamp/options.pl' ); for my $opt ( qw( -H --with-filename ) ) { my @expected = line_split( <<"HERE" ); $target_file:2:use strict; HERE my @files = qw( t/swamp/options.pl ); my @args = ( $opt, qw( strict ) ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, "Looking for strict in one file with $opt" ); } } WITH_SWITCHES_MULTIPLE_FILES: { for my $opt ( qw( -h --no-filename ) ) { my @expected = line_split( <<'HERE' ); use strict; HERE my @files = qw( t/swamp/options.pl t/swamp/crystallography-weenies.f ); my @args = ( $opt, qw( strict ) ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, "Looking for strict in multiple files with $opt" ); } } done_testing(); exit 0; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/config-backwards-compat.t��������������������������������������������������������������0000644�0001751�0001751�00000001434�14023027176�016236� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Util; use Test::More tests => 3; prep_environment(); my $temp_config = create_tempfile( <<'HERE' ); # Always sort --sort-files # I'm tired of grouping --noheading --break # Handle .hwd files --type-set=hwd=.hwd # Handle .md files --type-set=md=.mkd --type-add=md=.md # Handle .textile files --type-set=textile=.textile # Hooray for smart-case! --smart-case --ignore-dir=nytprof HERE my @args = ( '--ackrc=' . $temp_config->filename, '-t', 'md', 'One', 't/swamp/' ); my $file = reslash('t/swamp/notes.md'); my $line = 3; my ( $stdout, $stderr ) = run_ack_with_stderr( @args ); is( scalar(@{$stdout}), 1, 'Got back exactly one line' ); like $stdout->[0], qr/\Q$file:$line\E.*[*] One/; is_empty_array( $stderr, 'No output to stderr' ); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-g.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000020316�14023027176�012533� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 20; use lib 't'; use Util; prep_environment(); subtest 'No starting directory specified' => sub { plan tests => 3; my $regex = 'non'; my @files = qw( t/foo/non-existent ); my @args = ( '-g', $regex ); my ($stdout, $stderr) = run_ack_with_stderr( @args, @files ); is_empty_array( $stdout, 'No STDOUT for non-existent file' ); is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' ); like( $stderr->[0], qr/non-existent: No such file or directory/, 'Correct warning message for non-existent file' ); }; subtest 'regex comes before -g on the command line' => sub { plan tests => 3; my $regex = 'non'; my @files = qw( t/foo/non-existent ); my @args = ( $regex, '-g' ); my ($stdout, $stderr) = run_ack_with_stderr( @args, @files ); is_empty_array( $stdout, 'No STDOUT for non-existent file' ); is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' ); like( $stderr->[0], qr/non-existent: No such file or directory/, 'Correct warning message for non-existent file' ); }; subtest 'No metacharacters' => sub { plan tests => 1; my @expected = qw( t/swamp/Makefile t/swamp/Makefile.PL t/swamp/notaMakefile ); my $regex = 'Makefile'; my @args = ( '-g', $regex ); my @files = qw( t/ ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex" ); }; subtest 'With metacharacters' => sub { plan tests => 1; my @expected = qw( t/swamp/html.htm t/swamp/html.html ); my $regex = 'swam.......htm'; my @args = ( '-g', $regex ); my @files = qw( t/ ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex" ); }; subtest 'Front anchor' => sub { plan tests => 1; my @expected = qw( t/swamp/c-header.h t/swamp/c-source.c t/swamp/constitution-100k.pl t/swamp/crystallography-weenies.f ); my $regex = '^t.swamp.c'; my @args = ( '-g', $regex ); my @files = qw( t/swamp ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex" ); }; subtest 'Back anchor' => sub { plan tests => 1; my @expected = qw( t/swamp/constitution-100k.pl t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/perl.pl ); my $regex = 'pl$'; my @args = ( '-g', $regex ); my @files = qw( t/swamp ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex" ); }; subtest 'Case-insensitive via -i' => sub { plan tests => 1; my @expected = qw( t/swamp/pipe-stress-freaks.F ); my $regex = 'PIPE'; my @args = ( '-i', '-g', $regex ); my @files = qw( t/swamp ); ack_sets_match( [ @args, @files ], \@expected, "Looking for -i -g $regex " ); }; subtest 'Case-insensitive via (?i:)' => sub { plan tests => 1; my @expected = qw( t/swamp/pipe-stress-freaks.F ); my $regex = '(?i:PIPE)'; my @files = qw( t/swamp ); my @args = ( '-g', $regex ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex" ); }; subtest 'Negate -i via -I' => sub { plan tests => 1; my @expected = qw(); my $regex = 'PIPE'; my @args = ( '-i', '-I', '-g', $regex); my @files = qw( t/swamp ); ack_sets_match( [ @args, @files ], \@expected, "Looking for -i -I -g $regex" ); }; subtest 'Negate -I via -i' => sub { plan tests => 1; my @expected = qw( t/swamp/pipe-stress-freaks.F ); my $regex = 'PIPE'; my @args = ( '-I', '-i', '-g', $regex ); my @files = qw( t/swamp ); ack_sets_match( [ @args, @files ], \@expected, "Looking for -I -i -g $regex " ); }; subtest 'File on command line is always searched' => sub { plan tests => 1; my @expected = ( 't/swamp/#emacs-workfile.pl#' ); my $regex = 'emacs'; my @args = ( '-g', $regex ); my @files = ( 't/swamp/#emacs-workfile.pl#' ); ack_sets_match( [ @args, @files ], \@expected, 'File on command line is always searched' ); }; subtest 'File on command line is always searched, even with wrong filetype' => sub { plan tests => 1; my @expected = qw( t/swamp/notes.md ); my @files = qw( t/swamp/notes.md ); my @args = qw( -t html -g notes ); ack_sets_match( [ @args, @files ], \@expected, 'File on command line is always searched, even with wrong type.' ); }; subtest '-Q works on -g' => sub { plan tests => 2; # Matches without the -Q my @expected = qw( t/swamp/file.bar ); my $regex = 'file.bar$'; my @files = qw( t ); my @args = ( '-g', $regex ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex without -Q." ); # Doesn't match with -Q. ack_sets_match( [ @args, '-Q', @files ], [], "Looking for $regex with -Q." ); }; subtest '-w works on -g' => sub { plan tests => 1; my @expected = qw( t/text/number.txt ); my $regex = 'number'; # "number" shouldn't match "numbered" my @files = qw( t/text ); my @args = ( '-w', '-g', $regex, '--sort-files' ); ack_sets_match( [ @args, @files ], \@expected, "Looking for $regex with '-w'." ); }; subtest '-v works on -g' => sub { plan tests => 1; my @expected = qw( t/text/bill-of-rights.txt t/text/gettysburg.txt ); my $file_regex = 'n'; my @args = ( '-v', '-g', $file_regex, '--sort-files' ); my @files = qw( t/text/ ); ack_sets_match( [ @args, @files ], \@expected, "Looking for file names that do not match $file_regex" ); }; subtest '--smart-case works on -g' => sub { plan tests => 2; my @expected = qw( t/swamp/pipe-stress-freaks.F t/swamp/crystallography-weenies.f ); my @files = qw( t/swamp ); my @args = ( '--smart-case', '-g', 'f$' ); ack_sets_match( [ @args, @files ], \@expected, 'Looking for f$' ); @expected = qw( t/swamp/pipe-stress-freaks.F ); @args = ( '-S', '-g', 'F$' ); ack_sets_match( [ @args, @files ], \@expected, 'Looking for f$' ); }; subtest 'test exit codes' => sub { plan tests => 4; my $file_regex = 'foo'; my @files = ( 't/text/' ); run_ack( '-g', $file_regex, @files ); is( get_rc(), 1, '-g with no matches must exit with 1' ); $file_regex = 'raven'; run_ack( '-g', $file_regex, @files ); is( get_rc(), 0, '-g with matches must exit with 0' ); }; subtest 'test -g on a path' => sub { plan tests => 1; my $file_regex = 'text'; my @expected = qw( t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt ); my @args = ( '--sort-files', '-g', $file_regex, 't/text' ); ack_sets_match( [ @args ], \@expected, 'Make sure -g matches the whole path' ); }; subtest 'test -g with --color' => sub { plan tests => 2; my $file_regex = 'text'; my $expected_original = <<'HERE'; t/(text)/amontillado.txt t/(text)/bill-of-rights.txt t/(text)/constitution.txt t/(text)/gettysburg.txt t/(text)/number.txt t/(text)/numbered-(text).txt t/(text)/ozymandias.txt t/(text)/raven.txt HERE $expected_original = windows_slashify( $expected_original ) if is_windows; my @expected = colorize( $expected_original ); my @args = ( '--sort-files', '-g', $file_regex ); my @results = run_ack(@args, '--color', 't/text'); is_deeply( \@results, \@expected, 'Colorizing -g output with --color should work'); }; subtest q{test -g without --color; make sure colors don't show} => sub { if ( !has_io_pty() ) { plan skip_all => 'IO::Pty is required for this test'; return; } plan tests => 1; my $file_regex = 'text'; my $expected = <<'HERE'; t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt HERE my @args = ( '--sort-files', '-g', $file_regex, 't/text' ); my $results = run_ack_interactive(@args); is( $results, $expected, 'Colorizing -g output without --color should have no color' ); }; done_testing(); exit 0; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/bad-ackrc-opt.t������������������������������������������������������������������������0000644�0001751�0001751�00000000700�14023027176�014153� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Util; use Test::More tests => 4; prep_environment(); my ( $stdout, $stderr ) = run_ack_with_stderr( '--noenv', '--ackrc=./bad-ackrc', 'the', 't/text' ); is_empty_array( $stdout, 'Nothing to stdout' ); is( @{$stderr}, 1, 'only one line to stderr' ); like( $stderr->[0], qr/Unable to load ackrc/, 'Got the right message' ); isnt( get_rc(), 0, 'Non-zero return code' ); done_testing(); exit 0; ����������������������������������������������������������������ack-v3.5.0/t/runtests.pl����������������������������������������������������������������������������0000644�0001751�0001751�00000001515�14023027176�013610� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /usr/bin/perl #--------------------------------------------------------------------- # Run tests for ack # # Windows makes it hard to temporarily set environment variables, and # has horrible quoting rules, so what should be a one-liner gets its # own script. #--------------------------------------------------------------------- use ExtUtils::Command::MM; $ENV{PERL_DL_NONLAZY} = 1; $ENV{ACK_TEST_STANDALONE} = shift; defined($ENV{ACK_TEST_STANDALONE}) or die 'Must pass an argument to set ACK_TEST_STANDALONE'; # Make sure the tests' standard input is *never* a pipe (messes with ack's filter detection). open STDIN, '<', '/dev/null'; printf( "Running tests on %s, ACK_TEST_STANDALONE=%s\n", $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'blib/script/ack', $ENV{ACK_TEST_STANDALONE} ); test_harness(shift, shift, shift); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-w.barfly���������������������������������������������������������������������������0000644�0001751�0001751�00000004116�14023027176�013567� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# BEGIN comment here # # RUN # ack command line(s) # They should NOT be shell-escaped. Args are split on whitespace before # being passed in to ack. # # YESLINES # Lines that should match with underlines shown # ^^^^^^^^^^ # YES # Lines that should match, but without the underlines. # # NO # Lines that should not match. # # END # # Blank lines are always ignored. BEGIN Straight -w RUN ack -w foo YES foo foo bar NO foobar foot underfoot YESLINES foo-foo football ^^^ ^^^ foo ^^^ End of the line foo ^^^ I pity da foo'. ^^^ END BEGIN optional character RUN ack foot? YES foo foot Trampled underfoot foobarf foo-bar foo-bart football YESLINES Our ten-foot foo-bird is foobar. ^^^^ ^^^ ^^^ END BEGIN -w and optional character RUN ack -w foot? ack -w (foot?) ack -w (?:foot?) NO Trampled underfoot football foolish YES foo foot foo-bar foot-bar YESLINES foo ^^^ By the foot ^^^^ I pity da foo'. ^^^ Our ten-foot foo-bird is foobar. ^^^^ ^^^ END BEGIN -w and optional group RUN ack -w foo(bar)? YES foo foobar foo-bar foo-bart NO Trampled underfoot foobarf YESLINES foobar ^^^^^^ x foobar x ^^^^^^ I pity da foo'. ^^^ Now everything's all foobar. ^^^^^^ END BEGIN -w and alternation RUN ack -w foo|bar ack -w (foo|bar) YES foo bar NO schmfoo schmofool barfly fubar barometric subarometric YESLINES Little bunny foo-foo's ten-foot bar is foobar. ^^^ ^^^ ^^^ END BEGIN -w and a function definition RUN ack -w (set|get)_user_(name|perm) ack -w ((set|get)_user_(name|perm)) ack -w (?:(?:set|get)_user_(?:name|perm)) ack -w (?:(set|get)_user_(name|perm)) ack -w ((?:set|get)_user_(?:name|perm)) YES set_user_name get_user_perm NO reset_user_name get_user_permission YESLINES my $foo = set_user_name( $bar ) + set_user_perm( $foo ); ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ END BEGIN Single-letter words RUN ack -w \w YES A b c !E! NO dd xxx YESLINES A man, a plan, a canal: Panama ^ ^ ^ END # vi:set ft=barfly: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-s.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000002303�14023027176�012543� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More tests => 4; use lib 't'; use Util; use File::Temp; prep_environment(); WITHOUT_S: { my @files = qw( non-existent-file.txt ); my @args = qw( search-term ); my (undef, $stderr) = run_ack_with_stderr( @args, @files ); is( @{$stderr}, 1, 'Exactly one line of error' ); like( $stderr->[0], qr/\Qnon-existent-file.txt: No such file or directory\E/, q{Error if there's no file} ); } WITH_S: { my @files = qw( non-existent-file.txt ); my @args = qw( search-term -s ); my (undef, $stderr) = run_ack_with_stderr( @args, @files ); is_empty_array( $stderr, 'Nothing in stderr' ); } # Test on restricted directories. SKIP: { skip 'Fails under Travis. See GH#200.', 1 if $ENV{TRAVIS}; my @args = qw( hello -s ); my $dir = File::Temp->newdir; my $wd = getcwd_clean(); safe_chdir( $dir->dirname ); safe_mkdir( 'foo' ); write_file( 'foo/bar' => "hello\n" ); write_file( 'baz' => "hello\n" ); chmod 0000, 'foo'; chmod 0000, 'baz'; my (undef, $stderr) = run_ack_with_stderr( @args ); is_empty_array( $stderr, 'Nothing in stderr' ); safe_chdir( $wd ); } done_testing(); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/exit-code.t����������������������������������������������������������������������������0000644�0001751�0001751�00000000503�14023027176�013426� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Test::More tests => 4; use Util; prep_environment(); run_ack( 'legislative', 't/text/constitution.txt' ); is( get_rc(), 0, 'Exit code with matches should be 0' ); run_ack( 'foo', 't/text/constitution.txt' ); is( get_rc(), 1, 'Exit code with no matches should be 1' ); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-underline.t������������������������������������������������������������������������0000644�0001751�0001751�00000012305�14023027176�014271� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 8; use lib 't'; use Util; use Barfly; prep_environment(); # Run some basic tests. Barfly->run_tests( 't/ack-underline.barfly' ); # Most of the rest of this file is done manually rather than in Barfly # because Barfly relies on --underline working correctly. my $bill_ = reslash( 't/text/bill-of-rights.txt' ); my $getty = reslash( 't/text/gettysburg.txt' ); # Spacing that the filenames take up. my $spc_b = ' ' x length( $bill_ ); my $spc_g = ' ' x length( $getty ); subtest 'Single file' => sub { plan tests => 1; my @expected = line_split( <<'HERE' ); A well regulated Militia, being necessary to the security of a free State, ^^^^^^^ cases arising in the land or naval forces, or in the Militia, when in ^^^^^^^ HERE my @files = $bill_; my @args = ( qw( --underline ), 'Militia' ); ack_lists_match( [ @args, @files ], \@expected, 'Single file' ); }; subtest 'Grouped' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill_ 10:A well regulated Militia, being necessary to the security of a free State, ^^^^^^^ 31:cases arising in the land or naval forces, or in the Militia, when in ^^^^^^^ HERE my @files = qw( t/text/bill-of-rights.txt t/text/ozymandias.txt ); # Don't want Constitution in here. my @args = ( qw( --underline --group ), 'Militia' ); ack_lists_match( [ @args, @files ], \@expected, 'Grouped' ); }; subtest 'Not grouped, with leading filename' => sub { my @expected = line_split( <<"HERE" ); $bill_:10:A well regulated Militia, being necessary to the security of a free State, $spc_b ^^^^^^^ $bill_:31:cases arising in the land or naval forces, or in the Militia, when in $spc_b ^^^^^^^ HERE my $regex = 'Militia'; my @files = $bill_; my @args = ( qw( --underline --nogroup -H ), $regex ); ack_lists_match( [ @args, @files ], \@expected, "Looking for $regex - before with line numbers" ); }; subtest 'Grouped --underline' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill_ 4:or prohibiting the free exercise thereof; or abridging the freedom of ^^^^^^^ $getty 23:shall have a new birth of freedom -- and that government of the people, ^^^^^^^ HERE my @args = qw( --underline --sort-files --group freedom t/text ); ack_lists_match( [ @args ], \@expected, 'Looking for freedom, grouped' ); }; subtest 'Ungrouped --underline' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of $spc_b ^^^^^^^ $getty:23:shall have a new birth of freedom -- and that government of the people, $spc_g ^^^^^^^ HERE my @args = qw( --underline --sort-files --nogroup freedom t/text ); ack_lists_match( [ @args ], \@expected, 'Looking for freedom, ungrouped' ); }; subtest 'Grouped --underline with context' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill_ 2- 3-Congress shall make no law respecting an establishment of religion, 4:or prohibiting the free exercise thereof; or abridging the freedom of ^^^^^^^ 5-speech, or of the press; or the right of the people peaceably to assemble, 6-and to petition the Government for a redress of grievances. $getty 21-the last full measure of devotion -- that we here highly resolve that 22-these dead shall not have died in vain -- that this nation, under God, 23:shall have a new birth of freedom -- and that government of the people, ^^^^^^^ 24-by the people, for the people, shall not perish from the earth. HERE my @args = qw( --underline --sort-files --group -C free\w+ t/text ); ack_lists_match( [ @args ], \@expected, 'Looking for freedom, grouped with context' ); }; subtest 'Ungrouped --underline with --context' => sub { plan tests => 1; my @expected = line_split( <<"HERE" ); $bill_-2- $bill_-3-Congress shall make no law respecting an establishment of religion, $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of $spc_b ^^^^^^^ $bill_-5-speech, or of the press; or the right of the people peaceably to assemble, $bill_-6-and to petition the Government for a redress of grievances. -- $getty-21-the last full measure of devotion -- that we here highly resolve that $getty-22-these dead shall not have died in vain -- that this nation, under God, $getty:23:shall have a new birth of freedom -- and that government of the people, $spc_g ^^^^^^^ $getty-24-by the people, for the people, shall not perish from the earth. HERE my @args = qw( --underline --sort-files --nogroup -C free\w+ t/text ); ack_lists_match( [ @args ], \@expected, 'Looking for freedom, ungrouped' ); }; exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/file-permission.t����������������������������������������������������������������������0000644�0001751�0001751�00000004571�14023027176�014663� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # Make sure ack can handle files it can't read. use warnings; use strict; use Test::More; use lib 't'; use Util; use File::Spec; use File::Copy; use File::Temp; use constant NTESTS => 5; plan skip_all => q{Can't be checked under Win32} if is_windows(); plan skip_all => q{Can't be run as root} if $> == 0; plan tests => NTESTS; prep_environment(); my $temp_dir = File::Temp::newdir('temp.XXXX', CLEANUP => 1, EXLOCK => 0, TMPDIR => 1); my $target = File::Spec->catfile( $temp_dir, 'foo' ); copy( $0, $target ) or die "Can't copy $0 to $target"; my ($old_mode,$error) = make_unreadable( $target ); sub o { return sprintf '%o', shift } SKIP: { skip $error if $error; # Execute a search on this file. check_with( 'regex 1', $target ); # --count takes a different execution path check_with( 'regex 2', '--count', $target, { expected_stdout => 1, } ); my($volume,$path) = File::Spec->splitpath($target); # Run another test on the directory containing the read only file. check_with( 'notinthere', $volume . $path ); # Change permissions back. my $rc = chmod $old_mode, $target; ok( $rc, "Succeeded chmodding $target to " . o($old_mode) ); my (undef, undef, $back_mode) = stat($target); is( o($back_mode), o($old_mode), "${target}'s are back to what we expect" ); } done_testing(); sub check_with { local $Test::Builder::Level = $Test::Builder::Level + 1; my @args = @_; return subtest subtest_name( @args ) => sub { plan tests => 4; my $opts = {}; foreach my $arg ( @args ) { if ( ref($arg) eq 'HASH' ) { $opts = $arg; } } @args = grep { ref ne 'HASH' } @args; my $expected_stdout = $opts->{expected_stdout} || 0; my ($stdout, $stderr) = run_ack_with_stderr( @args ); is( get_rc(), 1, 'Exit code 1 for no output for grep compatibility' ); # Should be 2 for best grep compatibility since there was an error but we agreed that wasn't required. is( scalar @{$stdout}, $expected_stdout, 'No normal output' ) or diag(explain($stdout)); is( scalar @{$stderr}, 1, 'One line of stderr output' ) or diag(explain($stderr)); # Don't check for exact text of warning, the message text depends on LC_MESSAGES like( $stderr->[0], qr/\Q$target\E:/, 'Warning message OK' ); }; } ���������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/process-substitution.t�����������������������������������������������������������������0000644�0001751�0001751�00000001720�14023027176�015777� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Test::More; use Util; my @expected = ( 'THIS IS ALL IN UPPER CASE', 'this is a word here', ); prep_environment(); if ( is_windows() ) { plan skip_all => 'Test unreliable on Windows.'; } system 'bash', '-c', 'exit'; if ( $? ) { plan skip_all => 'You need bash to run this test'; exit; } plan tests => 1; my ( $read, $write ); pipe( $read, $write ); my $pid = fork(); my @output; if ( $pid ) { close $write; while ( <$read> ) { chomp; push @output, $_; } waitpid $pid, 0; } else { close $read; open STDOUT, '>&', $write or die "Can't open: $!"; open STDERR, '>&', $write or die "Can't open: $!"; my @args = adjust_executable( build_ack_invocation( qw( --noenv --nocolor --smart-case this ) ) ); my $args = join( ' ', @args ); exec 'bash', '-c', "$args <(cat t/swamp/options.pl)"; } lists_match( \@output, \@expected, __FILE__ ); exit 0; ������������������������������������������������ack-v3.5.0/t/ack-group.t����������������������������������������������������������������������������0000644�0001751�0001751�00000006144�14023027176�013444� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; use lib 't'; use Util; if ( not has_io_pty() ) { plan skip_all => q{You need to install IO::Pty to run this test}; exit(0); } plan tests => 8; prep_environment(); my ($bill_, $const, $getty) = map { reslash( "t/text/$_" ) } qw( bill-of-rights.txt constitution.txt gettysburg.txt ); my @TEXT_FILES = sort map { untaint($_) } glob( 't/text/*.txt' ); NO_GROUPING: { my @expected = line_split( <<"HERE" ); $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of $bill_:10:A well regulated Militia, being necessary to the security of a free State, $const:32:Number of free Persons, including those bound to Service for a Term $getty:23:shall have a new birth of freedom -- and that government of the people, HERE my @cases = ( [qw( --nogroup --nocolor free )], [qw( --nobreak --noheading --nocolor free )], ); for my $args ( @cases ) { my @results = run_ack_interactive( @{$args}, @TEXT_FILES ); lists_match( \@results, \@expected, 'No grouping' ); } } STANDARD_GROUPING: { my @expected = line_split( <<"HERE" ); $bill_ 4:or prohibiting the free exercise thereof; or abridging the freedom of 10:A well regulated Militia, being necessary to the security of a free State, $const 32:Number of free Persons, including those bound to Service for a Term $getty 23:shall have a new birth of freedom -- and that government of the people, HERE my @cases = ( [qw( --group --nocolor free )], [qw( --heading --break --nocolor free )], ); for my $args ( @cases ) { my @results = run_ack_interactive( @{$args}, @TEXT_FILES ); lists_match( \@results, \@expected, 'Standard grouping' ); } } HEADING_NO_BREAK: { my @expected = line_split( <<"HERE" ); $bill_ 4:or prohibiting the free exercise thereof; or abridging the freedom of 10:A well regulated Militia, being necessary to the security of a free State, $const 32:Number of free Persons, including those bound to Service for a Term $getty 23:shall have a new birth of freedom -- and that government of the people, HERE my @arg_sets = ( [qw( --heading --nobreak --nocolor free )], [qw( --nobreak --nocolor free )], ); for my $set ( @arg_sets ) { my @results = run_ack_interactive( @{$set}, @TEXT_FILES ); lists_match( \@results, \@expected, 'Heading, no break' ); } } BREAK_NO_HEADING: { my @expected = line_split( <<"HERE" ); $bill_:4:or prohibiting the free exercise thereof; or abridging the freedom of $bill_:10:A well regulated Militia, being necessary to the security of a free State, $const:32:Number of free Persons, including those bound to Service for a Term $getty:23:shall have a new birth of freedom -- and that government of the people, HERE my @arg_sets = ( [qw( --break --noheading --nocolor free )], [qw( --noheading --nocolor free )], ); for my $set ( @arg_sets ) { my @results = run_ack_interactive( @{$set}, @TEXT_FILES ); lists_match( \@results, \@expected, 'Break, no heading' ); } } done_testing(); exit 0; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-help-types.t�����������������������������������������������������������������������0000644�0001751�0001751�00000001261�14023027176�014375� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use List::Util qw(sum); use Test::More; use lib 't'; use Util; prep_environment(); my @types = ( perl => [qw{.pl .pod .pl .t}], python => [qw{.py}], ruby => [qw{.rb Rakefile}], ); plan tests => 11; my @output = run_ack( '--help-types' ); while ( my ($type,$checks) = splice( @types, 0, 2 ) ) { my ( $matching_line ) = grep { /^ $type / } @output; ok( $matching_line, "A match should be found for $type in the output for --help-types" ); foreach my $check (@{$checks}) { like( $matching_line, qr/\Q$check\E/, "Line for --$type in output for --help-types contains $check" ); } } done_testing(); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/noackrc.t������������������������������������������������������������������������������0000644�0001751�0001751�00000000762�14023027176�013174� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Test::More tests => 1; use Util; prep_environment(); my @expected = ( 't/swamp/Makefile.PL', 't/swamp/__pycache__/notes.pl', 't/swamp/constitution-100k.pl', 't/swamp/options-crlf.pl', 't/swamp/options.pl', 't/swamp/perl.pl', ); my @args = ( '--ignore-ack-defaults', '--type-add=perl:ext:pl', '-t', 'perl', '-f' ); my @files = ( 't/swamp' ); ack_sets_match( [ @args, @files ], \@expected, __FILE__ ); done_testing(); ��������������ack-v3.5.0/t/ack-1.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000003321�14023027176�012442� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 12; use lib 't'; use Util; prep_environment(); SINGLE_TEXT_MATCH: { my @expected = ( 'the catacombs of the Montresors.' ); my @files = qw( t/text ); my @args = qw( Montresor -1 -h --sort-files ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for first instance of Montresor!' ); } DASH_V: { my @expected = ( ' Only this and nothing more."' ); my @files = qw( t/text/raven.txt ); my @args = qw( c -1 -h -v ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Looking for first non-match' ); } DASH_F: { my @files = qw( t/swamp ); my @args = qw( -1 -f ); my @results = run_ack( @args, @files ); my $test_path = reslash( 't/swamp/' ); is( scalar @results, 1, 'Should only get one file back' ); like( $results[0], qr{^\Q$test_path\E}, 'One of the files from the swamp' ); } DASH_G: { my $regex = '\bMakefile\b'; my @files = qw( t/ ); my @args = ( '-1', '-g', $regex ); my @results = run_ack( @args, @files ); my $test_path = reslash( 't/swamp/Makefile' ); is( scalar @results, 1, "Should only get one file back from $regex" ); like( $results[0], qr{^\Q$test_path\E(?:[.]PL)?$}, 'The one file matches one of the two Makefile files' ); } DASH_L: { my @files = reslash( 't/text' ); my @args = qw( -1 -l --sort-files the ); # --sort-files to make sure we get the same first file each time. my @results = run_ack( @args, @files ); my $expected = reslash( 't/text/amontillado.txt' ); is_deeply( \@results, [$expected], 'Should only get one matching file back' ); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-show-types.t�����������������������������������������������������������������������0000644�0001751�0001751�00000002121�14023027176�014421� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 10; use lib 't'; use Util; prep_environment(); RUBY_AND_RAKE: { do_ruby_test( qw( -f --show-types t/swamp/Rakefile ) ); do_ruby_test( qw( -g \bRakef --show-types t/swamp ) ); } REQUIRE_F_OR_G: { my ( $stdout, $stderr ) = run_ack_with_stderr('--show-types'); is_empty_array($stdout, 'No output'); is(scalar(@{$stderr}), 1, 'A single line should be present on standard error'); like($stderr->[0], qr/--show-types can only be used with -f or -g./, 'Right error message' ); is(get_rc(), 255, 'The ack command should not fail'); } exit 0; sub do_ruby_test { local $Test::Builder::Level = $Test::Builder::Level + 1; my @args = @_; my @results = run_ack( @args ); is( scalar @results, 1, "Only one file should be returned from 'ack @args'" ); sets_match( get_types( $results[0] ), [qw( ruby rake )], "'ack @args' must return all the expected types" ); return; } sub get_types { my $line = shift; $line =~ s/.* => //; my @types = split( /,/, $line ); return \@types; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/mutex-options.t������������������������������������������������������������������������0000644�0001751�0001751�00000027476�14023027176�014422� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More tests => 196; use lib 't'; use Util; prep_environment(); my $file = 't/text/raven.txt'; my $word = 'nevermore'; # Order doesn't matter. They are reported in alphabetical order. for my $opt ( qw( -p --proximate ) ) { are_mutually_exclusive( '-f', $opt, ['-f', $opt] ); are_mutually_exclusive( '-f', $opt, [$opt, '-f'] ); } # Check for abbreviations. https://github.com/beyondgrep/ack3/issues/57 for my $opt ( qw( --pro --prox --proxima --proximat --proximate ) ) { are_mutually_exclusive( '-f', '--proximate', ['-f', $opt, '4'], ['-f', "$opt=4"], ); } # XXX Should also handle --files-with-matches and --files-without-matches. See https://github.com/beyondgrep/ack3/issues/57 are_mutually_exclusive('-l', '-L', ['-l', '-L', $word, $file]); for my $opt ( qw( -l -L ) ) { are_mutually_exclusive( $opt, '-o', [$opt, '-o', $word, $file] ); are_mutually_exclusive( $opt, '--passthru', [$opt, '--passthru', $word, $file] ); are_mutually_exclusive( $opt, '--output', [$opt, '--output', '$&', $word, $file] ); are_mutually_exclusive( $opt, '--output', [$opt, '--output=$&', $word, $file] ); are_mutually_exclusive( $opt, '-h', [$opt, '-h', $word, $file] ); are_mutually_exclusive( $opt, '--with-filename', [$opt, '--with-filename', $word, $file] ); are_mutually_exclusive( $opt, '--no-filename', [$opt, '--no-filename', $word, $file] ); are_mutually_exclusive( $opt, '--column', [$opt, '--column', $word, $file] ); are_mutually_exclusive( $opt, '-A', [$opt, '-A', 1, $word, $file] ); are_mutually_exclusive( $opt, '--after-context', [$opt, '--after-context', 1, $word, $file] ); are_mutually_exclusive( $opt, '--after-context', [$opt, '--after-context=1', $word, $file] ); are_mutually_exclusive( $opt, '-B', [$opt, '-B', 1, $word, $file] ); are_mutually_exclusive( $opt, '--before-context', [$opt, '--before-context', 1, $word, $file] ); are_mutually_exclusive( $opt, '--before-context', [$opt, '--before-context=1', $word, $file] ); are_mutually_exclusive( $opt, '-C', [$opt, '-C', 1, $word, $file] ); are_mutually_exclusive( $opt, '--context', [$opt, '--context', 1, $word, $file] ); are_mutually_exclusive( $opt, '--context', [$opt, '--context=1', $word, $file] ); are_mutually_exclusive( $opt, '--heading', [$opt, '--heading', $word, $file] ); are_mutually_exclusive( $opt, '--break', [$opt, '--break', $word, $file] ); are_mutually_exclusive( $opt, '--group', [$opt, '--group', $word, $file] ); are_mutually_exclusive( $opt, '-f', [$opt, '-f', $file] ); are_mutually_exclusive( $opt, '-g', [$opt, '-g', $word, $file] ); are_mutually_exclusive( $opt, '--show-types', [$opt, '--show-types', $word, $file] ); } # -o are_mutually_exclusive( '-o', '--output', ['-o', '--output', '$&', $word, $file], ['-o', '--output=$&', $word, $file], ); are_mutually_exclusive('-o', '-c', ['-o', '-c', $word, $file]); are_mutually_exclusive('-o', '--count', ['-o', '--count', $word, $file]); are_mutually_exclusive('-o', '--column', ['-o', '--column', $word, $file]); are_mutually_exclusive('-o', '-A', ['-o', '-A', 1, $word, $file]); are_mutually_exclusive('-o', '--after-context', ['-o', '--after-context', 1, $word, $file]); are_mutually_exclusive('-o', '--after-context', ['-o', '--after-context=1', $word, $file]); are_mutually_exclusive('-o', '-B', ['-o', '-B', 1, $word, $file]); are_mutually_exclusive('-o', '--before-context', ['-o', '--before-context', 1, $word, $file]); are_mutually_exclusive('-o', '--before-context', ['-o', '--before-context=1', $word, $file]); are_mutually_exclusive('-o', '-C', ['-o', '-C', 1, $word, $file]); are_mutually_exclusive('-o', '--context', ['-o', '--context', 1, $word, $file]); are_mutually_exclusive('-o', '--context', ['-o', '--context=1', $word, $file]); are_mutually_exclusive('-o', '-f', ['-o', '-f', $word, $file]); are_mutually_exclusive('-o', '--passthru', ['-o', '--passthru', $word, $file]); # --passthru are_mutually_exclusive('--passthru', '--output', ['--passthru', '--output', '$&', $word, $file]); are_mutually_exclusive('--passthru', '--output', ['--passthru', '--output=$&', $word, $file]); are_mutually_exclusive('--passthru', '-m', ['--passthru', '-m', 1, $word, $file]); are_mutually_exclusive('--passthru', '--max-count', ['--passthru', '--max-count', 1, $word, $file]); are_mutually_exclusive('--passthru', '--max-count', ['--passthru', '--max-count=1', $word, $file]); are_mutually_exclusive('--passthru', '-1', ['--passthru', '-1', $word, $file]); are_mutually_exclusive('--passthru', '-c', ['--passthru', '-c', $word, $file]); are_mutually_exclusive('--passthru', '--count', ['--passthru', '--count', $word, $file]); are_mutually_exclusive('--passthru', '-A', ['--passthru', '-A', 1, $word, $file]); are_mutually_exclusive('--passthru', '--after-context', ['--passthru', '--after-context', 1, $word, $file]); are_mutually_exclusive('--passthru', '--after-context', ['--passthru', '--after-context=1', $word, $file]); are_mutually_exclusive('--passthru', '-B', ['--passthru', '-B', 1, $word, $file]); are_mutually_exclusive('--passthru', '--before-context', ['--passthru', '--before-context', 1, $word, $file]); are_mutually_exclusive('--passthru', '--before-context', ['--passthru', '--before-context=1', $word, $file]); are_mutually_exclusive('--passthru', '-C', ['--passthru', '-C', 1, $word, $file]); are_mutually_exclusive('--passthru', '--context', ['--passthru', '--context', 1, $word, $file]); are_mutually_exclusive('--passthru', '--context', ['--passthru', '--context=1', $word, $file]); are_mutually_exclusive('--passthru', '-f', ['--passthru', '-f', $word, $file]); are_mutually_exclusive('--passthru', '-g', ['--passthru', '-g', $word, $file]); are_mutually_exclusive('--passthru', '--column', ['--passthru', '--column', $word, $file]); are_mutually_exclusive('--passthru', '-v', ['--passthru', '-v', $word, $file]); are_mutually_exclusive('--passthru', '-o', ['--passthru', '-o', $word, $file]); are_mutually_exclusive('--passthru', '--output', ['--passthru', '--output', $word, $file]); # --output for my $opt ( qw( -f -g -c --count ) ) { are_mutually_exclusive('--output', $opt, ['--output', '$&', $opt, $word, $file], ['--output=$&', $opt, $word, $file], ); } are_mutually_exclusive('--output', '-A', ['--output=$&', '-A2', $word, $file]); are_mutually_exclusive('--output', '-B', ['--output=$&', '-B2', $word, $file]); are_mutually_exclusive('--output', '-C', ['--output=$&', '-C2', $word, $file]); are_mutually_exclusive('--output', '--after-context', ['--output=$&', '--after-context=2', $word, $file]); are_mutually_exclusive('--output', '--before-context', ['--output=$&', '--before-context=2', $word, $file]); are_mutually_exclusive('--output', '--context', ['--output=$&', '--context=2', $word, $file]); # --match for my $opt ( qw( -f -g ) ) { are_mutually_exclusive('--match', $opt, ['--match', $word, $opt, $file], ['--match=science', $opt, $file], ); } # --max-count for my $opt ( qw( -1 -c -f -g ) ) { are_mutually_exclusive( '-m', $opt, ['-m', 1, $opt, $word, $file] ); are_mutually_exclusive( '--max-count', $opt, ['--max-count', 1, $opt, $word, $file], ['--max-count=1', $opt, $word, $file], ); } for my $opt ( qw( -h --no-filename ) ) { are_mutually_exclusive( $opt, '-f', [$opt, '-f', $word, $file] ); are_mutually_exclusive( $opt, '-g', [$opt, '-g', $word, $file] ); } # -H/--with-filename for my $opt ( qw( -H --with-filename ) ) { are_mutually_exclusive( $opt, '-f', [ $opt, '-f', $word, $file] ); are_mutually_exclusive( $opt, '-g', [ $opt, '-g', $word, $file] ); } # -c/--count for my $opt ( qw( -c --count ) ) { are_mutually_exclusive( $opt, '--column', [ $opt, '--column', $word, $file ] ); are_mutually_exclusive( $opt, '-A', [ $opt, '-A', 1, $word, $file ] ); are_mutually_exclusive( $opt, '--after-context', [ $opt, '--after-context', 1, $word, $file ] ); are_mutually_exclusive( $opt, '-B', [ $opt, '-B', 1, $word, $file ] ); are_mutually_exclusive( $opt, '--before-context', [ $opt, '--before-context', 1, $word, $file ] ); are_mutually_exclusive( $opt, '-C', [ $opt, '-C', 1, $word, $file ] ); are_mutually_exclusive( $opt, '--context', [ $opt, '--context', 1, $word, $file ] ); are_mutually_exclusive( $opt, '--heading', [ $opt, '--heading', $word, $file ] ); are_mutually_exclusive( $opt, '--group', [ $opt, '--group', $word, $file ] ); are_mutually_exclusive( $opt, '--break', [ $opt, '--break', $word, $file ] ); are_mutually_exclusive( $opt, '-f', [ $opt, '-f', $word, $file ] ); are_mutually_exclusive( $opt, '-g', [ $opt, '-g', $word, $file ] ); } # -A/-B/-C/--after-context/--before-context/--context for my $opt ( qw( -A -B -C --after-context --before-context --context ) ) { are_mutually_exclusive( $opt, '-f', [$opt, 1, '-f', $word, $file] ); are_mutually_exclusive( $opt, '-g', [$opt, 1, '-g', $word, $file] ); are_mutually_exclusive( $opt, '-p', [$opt, 1, '-p', $word, $file] ); } # -f/-g are_mutually_exclusive('-f', '-g', ['-f', '-g', $word, $file]); for my $opt ( qw( -f -g ) ) { are_mutually_exclusive( $opt, '--group', [$opt, '--group', $word, $file] ); are_mutually_exclusive( $opt, '--heading', [$opt, '--heading', $word, $file] ); are_mutually_exclusive( $opt, '--break', [$opt, '--break', $word, $file] ); are_mutually_exclusive( $opt, '--column', [$opt, '--column', $word, $file] ); } # -x are_mutually_exclusive( '-x', '--files-from', ['-x', '--files-from', $word, $file] ); for my $opt ( qw( -f -g ) ) { are_mutually_exclusive( $opt, '-x', [$opt, '-x', $word, $file] ); are_mutually_exclusive( $opt, '--files-from', [$opt, '--files-from', $word, $file] ); } subtest q{Verify that "options" that follow -- aren't factored into the mutual exclusivity} => sub { my ( $stdout, $stderr ) = run_ack_with_stderr('-A', 5, $word, $file, '--', '-l'); ok(@{$stdout} > 0, 'Some lines should appear on standard output'); is(scalar(@{$stderr}), 1, 'A single line should be present on standard error'); like($stderr->[0], qr/No such file or directory/, 'The error message should indicate a missing file (-l is a filename here, not an option)'); is(get_rc(), 0, 'The ack command should not fail'); }; subtest q{Verify that mutex options in different sources don't cause a problem} => sub { my $ackrc = <<'HERE'; --group HERE my @stdout = run_ack('--count', $file, { ackrc => \$ackrc, }); ok(@stdout > 0, 'Some lines should appear on standard output'); }; done_testing(); # Do this without system(). sub are_mutually_exclusive { local $Test::Builder::Level = $Test::Builder::Level + 1; my $opt1 = shift; my $opt2 = shift; my @argsets = @_; @argsets or die 'Must pass argsets'; for my $argset ( @argsets ) { my @args = @{$argset}; my ( $stdout, $stderr ) = run_ack_with_stderr(@args); subtest subtest_name( $opt1, $opt2, $argset ) => sub { plan tests => 4; isnt( get_rc(), 0, 'The ack command should fail' ); is_empty_array( $stdout, 'No lines should be present on standard output' ); is( scalar(@{$stderr}), 1, 'A single line should be present on standard error' ); my $opt1_re = quotemeta($opt1); my $opt2_re = quotemeta($opt2); my $error = $stderr->[0] || ''; # avoid undef warnings if ( $error =~ /Options '$opt1_re' and '$opt2_re' can't be used together/ || $error =~ /Options '$opt2_re' and '$opt1_re' can't be used together/ ) { pass( qq{Error message resembles "Options '$opt1' and '$opt2' can't be used together"} ); } else { fail( qq{Error message does not resemble "Options '$opt1' and '$opt2' can't be used together"} ); diag("Error message: '$error'"); } }; } return; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/needs-line-scan.t����������������������������������������������������������������������0000644�0001751�0001751�00000000631�14023027176�014514� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 1; use lib 't'; use Util; prep_environment(); # The "bongo" match is after the 100,000-byte cutoff. NEEDS_LINE_SCAN: { my @expected = line_split( <<'HERE' ); my $bongo = 'yada yada'; HERE my @files = qw( t/swamp ); my @args = qw( bongo -w -h ); ack_lists_match( [ @args, @files ], \@expected, 'Looking for Lenore!' ); } exit 0; �������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-files-from.t�����������������������������������������������������������������������0000644�0001751�0001751�00000005745�14023027176�014361� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Test::More tests => 6; use Util; prep_environment(); my @textfiles = qw( t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/ozymandias.txt t/text/raven.txt ); subtest 'Basic reading from files, no switches' => sub { plan tests => 1; my $target_file = reslash( 't/swamp/options.pl' ); my @expected = line_split( <<"HERE" ); $target_file:2:use strict; HERE my $tempfile = create_tempfile( qw( t/swamp/options.pl t/swamp/pipe-stress-freaks.F ) ); ack_lists_match( [ '--files-from=' . $tempfile->filename, 'strict' ], \@expected, 'Looking for strict in multiple files' ); unlink $tempfile->filename; }; subtest 'Non-existent file specified' => sub { plan tests => 3; my @args = qw( strict ); my ( $stdout, $stderr ) = run_ack_with_stderr( '--files-from=non-existent-file', @args); is_empty_array( $stdout, 'No STDOUT for non-existent file' ); is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' ); like( $stderr->[0], qr/Unable to open non-existent-file:/, 'Correct warning message for non-existent file' ); }; subtest 'Source file exists, but non-existent files mentioned in the file' => sub { plan tests => 4; my $tempfile = create_tempfile( qw( t/swamp/options.pl file-that-isnt-there ) ); my ( $stdout, $stderr ) = run_ack_with_stderr( '--files-from=' . $tempfile->filename, 'CASE'); is( scalar @{$stdout}, 1, 'One hit found' ); like( $stdout->[0], qr/THIS IS ALL IN UPPER CASE/, 'Find the one line in the file' ); is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' ); like( $stderr->[0], qr/file-that-isnt-there: No such file/, 'Correct warning message for non-existent file' ); }; subtest '-l and --files-from' => sub { plan tests => 1; my $tempfile = create_tempfile( @textfiles ); my @expected = qw( t/text/amontillado.txt t/text/gettysburg.txt t/text/raven.txt ); ack_sets_match( [ '--files-from=' . $tempfile->filename, 'God', '-l' ], \@expected, 'Looking for God files' ); }; subtest '-L and --files-from' => sub { plan tests => 1; my $tempfile = create_tempfile( @textfiles ); my @expected = qw( t/text/bill-of-rights.txt t/text/constitution.txt t/text/ozymandias.txt ); ack_sets_match( [ '--files-from=' . $tempfile->filename, 'God', '-L' ], \@expected, 'Looking for absence of God' ); }; subtest '-c and --files-from' => sub { plan tests => 1; my $tempfile = create_tempfile( @textfiles ); my @expected = qw( t/text/amontillado.txt:2 t/text/bill-of-rights.txt:0 t/text/constitution.txt:0 t/text/gettysburg.txt:1 t/text/ozymandias.txt:0 t/text/raven.txt:2 ); ack_sets_match( [ '--files-from=' . $tempfile->filename, 'God', '-c' ], \@expected, 'Looking for God files' ); }; done_testing(); exit 0; ���������������������������ack-v3.5.0/t/command-line-files.t�������������������������������������������������������������������0000644�0001751�0001751�00000003203�14023027176�015210� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # This file validates behaviors of specifying files on the command line. use warnings; use strict; use Test::More tests => 4; use lib 't'; use Util; prep_environment(); my @source_files = map { reslash($_) } qw( t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/options.pl.bak ); JUST_THE_DIR: { my @expected = line_split( <<"HERE" ); $source_files[0]:19:notawordhere $source_files[1]:19:notawordhere HERE my @files = qw( t/swamp ); my @args = qw( notaword ); ack_sets_match( [ @args, @files ], \@expected, q{One hit for specifying a dir} ); } # Even a .bak file gets searched if you specify it on the command line. SPECIFYING_A_BAK_FILE: { my @expected = line_split( <<"HERE" ); $source_files[1]:19:notawordhere $source_files[2]:19:notawordhere HERE my @files = qw( t/swamp/options.pl t/swamp/options.pl.bak ); my @args = qw( notaword ); ack_sets_match( [ @args, @files ], \@expected, q{Two hits for specifying the file} ); } FILE_NOT_THERE: { my $file = reslash( 't/swamp/perl.pod' ); my $filename = $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'ack'; my @expected_stderr = ( "$filename: non-existent-file.txt: No such file or directory" ); my @expected_stdout = line_split( <<"HERE" ); ${file}:3:=head2 There's important stuff in here! HERE my @files = ( 'non-existent-file.txt', $file ); my @args = qw( head2 ); my ($stdout, $stderr) = run_ack_with_stderr( @args, @files ); lists_match( $stderr, \@expected_stderr, q{Error if there's no file} ); lists_match( $stdout, \@expected_stdout, 'Find the one file that has a hit' ); } exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/filetypes.t����������������������������������������������������������������������������0000644�0001751�0001751�00000004723�14023027176�013561� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 19; use lib 't'; use Util; prep_environment(); my %types_for_file; populate_filetypes(); sets_match( [filetypes( 't/swamp/perl.pod' )], [qw( perl pod )], 'foo.pod can be multiple things' ); sets_match( [filetypes( 't/swamp/perl.pm' )], [qw( perl )], 't/swamp/perl.pm' ); sets_match( [filetypes( 't/swamp/Makefile.PL' )], [qw( perl )], 't/swamp/Makefile.PL' ); sets_match( [filetypes( 'Unknown.wango' )], [], 'Unknown' ); ok( is_filetype( 't/swamp/perl.pod', 'perl' ), 'foo.pod can be perl' ); ok( is_filetype( 't/swamp/perl.pod', 'pod' ), 'foo.pod can be pod' ); ok( !is_filetype( 't/swamp/perl.pod', 'ruby' ), 'foo.pod cannot be ruby' ); ok( is_filetype( 't/swamp/perl.handler.pod', 'perl' ), 'perl.handler.pod can be perl' ); ok( is_filetype( 't/swamp/Makefile', 'make' ), 'Makefile is a makefile' ); ok( is_filetype( 't/swamp/Rakefile', 'rake' ), 'Rakefile is a rakefile' ); is_empty_array( [filetypes('t/swamp/#emacs-workfile.pl#')], 'correctly skip files starting and ending with hash mark' ); MATCH_VIA_CONTENT: { my %lookups = ( 't/swamp/Makefile' => 'make', 't/swamp/Makefile.PL' => 'perl', 't/etc/shebang.php.xxx' => 'php', 't/etc/shebang.pl.xxx' => 'perl', 't/etc/shebang.py.xxx' => 'python', 't/etc/shebang.rb.xxx' => 'ruby', 't/etc/shebang.sh.xxx' => 'shell', 't/etc/buttonhook.xml.xxx' => 'xml', ); for my $filename ( sort keys %lookups ) { my $type = $lookups{$filename}; sets_match( [filetypes( $filename )], [ $type ], "Checking $filename" ); } } done_testing; exit 0; sub populate_filetypes { my ( $type_lines, undef ) = run_ack_with_stderr('--help-types'); my @types_to_try; foreach my $line ( @{$type_lines} ) { if ( $line =~ /^ (\w+) / ) { push @types_to_try, $1; } } foreach my $type (@types_to_try) { my ( $filenames, undef ) = run_ack_with_stderr('-f', '-t', $type, 't/swamp', 't/etc'); foreach my $filename ( @{$filenames} ) { push @{ $types_for_file{$filename} }, $type; } } return; } sub filetypes { my $filename = reslash(shift); return @{ $types_for_file{$filename} || [] }; } sub is_filetype { my ( $filename, $wanted_type ) = @_; for my $maybe_type ( filetypes( $filename ) ) { return 1 if $maybe_type eq $wanted_type; } return 0; } ���������������������������������������������ack-v3.5.0/t/ack-k.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000005715�14023027176�012545� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 3; use lib 't'; use Util; prep_environment(); subtest 'No restrictions on type' => sub { my $expected = <<'HERE'; t/etc/buttonhook.xml.xxx => xml t/etc/shebang.empty.xxx => t/etc/shebang.foobar.xxx => t/etc/shebang.php.xxx => php t/etc/shebang.pl.xxx => perl t/etc/shebang.py.xxx => python t/etc/shebang.rb.xxx => ruby t/etc/shebang.sh.xxx => shell HERE my @expected = reslash_all( line_split( $expected ) ); my @args = qw( -f --show-types t/etc ); ack_sets_match( [ @args ], \@expected, 'No restrictions on type' ); }; subtest 'Only known types' => sub { my $expected = <<'HERE'; t/etc/buttonhook.xml.xxx => xml t/etc/shebang.php.xxx => php t/etc/shebang.pl.xxx => perl t/etc/shebang.py.xxx => python t/etc/shebang.rb.xxx => ruby t/etc/shebang.sh.xxx => shell HERE my @expected = reslash_all( line_split( $expected ) ); my @args = qw( -f -k --show-types t/etc ); ack_sets_match( [ @args ], \@expected, 'Only known types' ); }; subtest 'More testing' => sub { plan tests => 4; my @files = qw( t/swamp/0 t/swamp/constitution-100k.pl t/swamp/Rakefile t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/javascript.js t/swamp/html.html t/swamp/perl-without-extension t/swamp/sample.rake t/swamp/perl.cgi t/swamp/Makefile t/swamp/pipe-stress-freaks.F t/swamp/perl.pod t/swamp/html.htm t/swamp/perl-test.t t/swamp/perl.handler.pod t/swamp/perl.pl t/swamp/Makefile.PL t/swamp/MasterPage.master t/swamp/c-source.c t/swamp/perl.pm t/swamp/c-header.h t/swamp/crystallography-weenies.f t/swamp/CMakeLists.txt t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.asp t/swamp/sample.aspx t/swamp/service.svc t/swamp/stuff.cmake t/swamp/example.R t/swamp/fresh.css t/swamp/lua-shebang-test t/swamp/notes.md ); my @files_no_perl = qw( t/swamp/Rakefile t/swamp/javascript.js t/swamp/html.html t/swamp/sample.rake t/swamp/Makefile t/swamp/MasterPage.master t/swamp/pipe-stress-freaks.F t/swamp/html.htm t/swamp/c-source.c t/swamp/c-header.h t/swamp/crystallography-weenies.f t/swamp/CMakeLists.txt t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.asp t/swamp/sample.aspx t/swamp/service.svc t/swamp/stuff.cmake t/swamp/example.R t/swamp/fresh.css t/swamp/lua-shebang-test t/swamp/notes.md ); for my $k_arg ( '-k', '--known-types' ) { ack_sets_match( [ $k_arg, '-f', 't/swamp' ], \@files, "$k_arg test #1" ); ack_sets_match( [ $k_arg, '-T', 'perl', '-f', 't/swamp' ], \@files_no_perl, "$k_arg test #2" ); } }; done_testing(); exit 0; ���������������������������������������������������ack-v3.5.0/t/Util.pm��������������������������������������������������������������������������������0000644�0001751�0001751�00000071123�14023027176�012641� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package Util; use 5.010001; use parent 'Exporter'; use warnings; use strict; use Carp (); use Cwd (); use File::Next (); use File::Spec (); use File::Temp (); use Scalar::Util qw( tainted ); use Term::ANSIColor (); use Test::More; our @EXPORT = qw( prep_environment create_globals clean_up_globals touch_ackrc has_io_pty is_windows is_cygwin is_empty_array is_nonempty_array first_line_like build_ack_invocation adjust_executable read_file write_file append_file create_tempfile touch reslash reslash_all windows_slashify run_cmd run_ack run_ack_with_stderr run_ack_interactive run_piped pipe_into_ack pipe_into_ack_with_stderr lists_match sets_match ack_lists_match ack_sets_match ack_error_matches untaint line_split colorize get_expected_options caret_X get_rc getcwd_clean filter_out_perldoc_noise make_unreadable safe_chdir safe_mkdir msg subtest_name ); my $orig_wd; my @temp_files; # We store temp files here to make sure they're properly reclaimed at interpreter shutdown. sub prep_environment { my @ack_args = qw( ACKRC ACK_PAGER HOME ACK_COLOR_MATCH ACK_COLOR_FILENAME ACK_COLOR_LINENO ACK_COLOR_COLNO ); my @taint_args = qw( PATH CDPATH IFS ENV ); delete @ENV{ @ack_args, @taint_args }; if ( is_windows() ) { # To pipe, perl must be able to find cmd.exe, so add %SystemRoot%\system32 to the path. # See http://kstruct.com/2006/09/13/perl-taint-mode-and-cmdexe/ $ENV{SystemRoot} =~ /([A-Z]:(\\[A-Z0-9_]+)+)/i or die 'Unrecognizable SystemRoot'; my $system32_dir = File::Spec->catdir($1,'system32'); $ENV{'PATH'} = $system32_dir; } $orig_wd = getcwd_clean(); return; } sub is_windows { return $^O eq 'MSWin32'; } sub is_cygwin { return ($^O eq 'cygwin' || $^O eq 'msys'); } sub is_empty_array { local $Test::Builder::Level = $Test::Builder::Level + 1; my $aref = shift; my $msg = shift; my $ok = defined($aref) && (ref($aref) eq 'ARRAY') && (scalar(@{$aref}) == 0); if ( !ok( $ok, $msg ) ) { diag( explain( $aref ) ); } return $ok; } sub is_nonempty_array { local $Test::Builder::Level = $Test::Builder::Level + 1; my $aref = shift; my $msg = shift; my $ok = defined($aref) && (ref($aref) eq 'ARRAY') && (scalar(@{$aref}) > 0); if ( !ok( $ok, $msg ) ) { diag( explain( $aref ) ); } return $ok; } sub first_line_like { local $Test::Builder::Level = $Test::Builder::Level + 1; my $lines = shift; my $re = shift; my $msg = shift; my $ok = like( $lines->[0], $re, $msg ); diag(explain($lines)) unless $ok; return $ok; } sub build_ack_invocation { my @args = @_; my $options; foreach my $arg ( @args ) { if ( ref($arg) eq 'HASH' ) { if ( $options ) { die 'You may not specify more than one options hash'; } else { $options = $arg; } } } $options ||= {}; if ( my $ackrc = $options->{ackrc} ) { if ( ref($ackrc) eq 'SCALAR' ) { my $temp_ackrc = create_tempfile( ${$ackrc} ); push @temp_files, $temp_ackrc; $ackrc = $temp_ackrc->filename; } unshift @args, '--ackrc', $ackrc; } # The --noenv makes sure we don't pull in anything from the user # unless explicitly specified in the test if ( !grep { /^--(no)?env$/ } @args ) { unshift( @args, '--noenv' ); } if ( $ENV{'ACK_TEST_STANDALONE'} ) { unshift( @args, File::Spec->rel2abs( 'ack-standalone', $orig_wd ) ); } else { unshift( @args, File::Spec->rel2abs( 'blib/script/ack', $orig_wd ) ); } return @args; } # Use this instead of File::Slurp::read_file() sub read_file { my $filename = shift; open( my $fh, '<', $filename ) or die "Can't read $filename: \n"; my @lines = <$fh>; close $fh or die; return wantarray ? @lines : join( '', @lines ); } # Use this instead of File::Slurp::write_file() sub write_file { return _write_file( '>', 'create', @_ ); } # Use this instead of File::Slurp::append_file() sub append_file { return _write_file( '>>', 'append', @_ ); } sub _write_file { my $op = shift; my $verb = shift; my $filename = shift; my @lines = @_; open( my $fh, $op, $filename ) or die "Can't $verb $filename: \n"; for my $line ( @lines ) { print {$fh} $line; } close $fh or die; return; } sub line_split { return split( /\n/, $_[0] ); } sub reslash { return File::Next::reslash( shift ); } sub reslash_all { return map { File::Next::reslash( $_ ) } @_; } sub run_ack { local $Test::Builder::Level = $Test::Builder::Level + 1; my @args = @_; my ($stdout, $stderr) = run_ack_with_stderr( @args ); @args = grep { ref ne 'HASH' } @args; if ( $TODO ) { fail( q{Automatically fail stderr check for TODO tests.} ); } else { is_empty_array( $stderr, "Should have no output to stderr: ack @args" ); } return wantarray ? @{$stdout} : join( "\n", @{$stdout} ); } { # scope for $ack_return_code; # Capture return code. our $ack_return_code; # Run the given command, assuming that the command was created with # build_ack_invocation (and thus writes its STDERR to $catcherr_file). # # Sets $ack_return_code and unlinks the $catcherr_file. # # Returns chomped STDOUT and STDERR as two array refs. sub run_cmd { my ( @cmd ) = @_; my $options = {}; foreach my $arg (@cmd) { if ( ref($arg) eq 'HASH' ) { $options = $arg; } } @cmd = grep { ref ne 'HASH' } @cmd; _record_option_coverage(@cmd); _check_command_for_taintedness( @cmd ); my ( @stdout, @stderr ); if ( is_windows() ) { ## no critic ( InputOutput::ProhibitTwoArgOpen ) ## no critic ( InputOutput::ProhibitBarewordFileHandles ) require Win32::ShellQuote; # Capture stderr & stdout output into these files (only on Win32). my $tempdir = File::Temp->newdir; my $catchout_file = File::Spec->catfile( $tempdir->dirname, 'stdout.log' ); my $catcherr_file = File::Spec->catfile( $tempdir->dirname, 'stderr.log' ); open(SAVEOUT, '>&STDOUT') or die "Can't dup STDOUT: $!"; open(SAVEERR, '>&STDERR') or die "Can't dup STDERR: $!"; open(STDOUT, '>', $catchout_file) or die "Can't open $catchout_file: $!"; open(STDERR, '>', $catcherr_file) or die "Can't open $catcherr_file: $!"; my $cmd = Win32::ShellQuote::quote_system_string(@cmd); if ( my $input = $options->{input} ) { my $input_command = Win32::ShellQuote::quote_system_string(@{$input}); $cmd = "$input_command | $cmd"; } system( $cmd ); close STDOUT; close STDERR; open(STDOUT, '>&SAVEOUT') or die "Can't restore STDOUT: $!"; open(STDERR, '>&SAVEERR') or die "Can't restore STDERR: $!"; close SAVEOUT; close SAVEERR; @stdout = read_file($catchout_file); @stderr = read_file($catcherr_file); } else { my ( $stdout_read, $stdout_write ); my ( $stderr_read, $stderr_write ); pipe $stdout_read, $stdout_write or die "Unable to create pipe: $!"; pipe $stderr_read, $stderr_write or die "Unable to create pipe: $!"; my $pid = fork(); if ( $pid == -1 ) { die "Unable to fork: $!"; } if ( $pid ) { close $stdout_write; close $stderr_write; while ( $stdout_read || $stderr_read ) { my $rin = ''; vec( $rin, fileno($stdout_read), 1 ) = 1 if $stdout_read; vec( $rin, fileno($stderr_read), 1 ) = 1 if $stderr_read; select( $rin, undef, undef, undef ); if ( $stdout_read && vec( $rin, fileno($stdout_read), 1 ) ) { my $line = <$stdout_read>; if ( defined( $line ) ) { push @stdout, $line; } else { close $stdout_read; undef $stdout_read; } } if ( $stderr_read && vec( $rin, fileno($stderr_read), 1 ) ) { my $line = <$stderr_read>; if ( defined( $line ) ) { push @stderr, $line; } else { close $stderr_read; undef $stderr_read; } } } waitpid $pid, 0; } else { close $stdout_read; close $stderr_read; if (my $input = $options->{input}) { _check_command_for_taintedness( @{$input} ); open STDIN, '-|', @{$input} or die "Can't open STDIN: $!"; } open STDOUT, '>&', $stdout_write or die "Can't open STDOUT: $!"; open STDERR, '>&', $stderr_write or die "Can't open STDERR: $!"; exec @cmd; } } # end else not Win32 my ($sig,$core,$rc) = (($? & 127), ($? & 128), ($? >> 8)); ## no critic ( Bangs::ProhibitBitwiseOperators Variables::ProhibitUnusedVarsStricter ) $ack_return_code = $rc; ## XXX what to do with $core or $sig? chomp @stdout; chomp @stderr; return ( \@stdout, \@stderr ); } sub get_rc { return $ack_return_code; } } # scope for $ack_return_code sub run_ack_with_stderr { my @args = @_; @args = adjust_executable( build_ack_invocation( @args ) ); return run_cmd( @args ); } sub run_piped { my $lhs_args = shift; my $rhs_args = shift; my $stdout; my $stderr; my ( $stdout_read, $stdout_write ); my ( $stderr_read, $stderr_write ); my ( $lhs_rhs_read, $lhs_rhs_write ); pipe( $stdout_read, $stdout_write ); pipe( $stderr_read, $stderr_write ); pipe( $lhs_rhs_read, $lhs_rhs_write ); my $lhs_pid; my $rhs_pid; $lhs_pid = fork(); if ( !defined($lhs_pid) ) { die 'Unable to fork'; } if ( $lhs_pid ) { $rhs_pid = fork(); if ( !defined($rhs_pid) ) { kill TERM => $lhs_pid; waitpid $lhs_pid, 0; die 'Unable to fork'; } } if ( $rhs_pid ) { # parent close $stdout_write; close $stderr_write; close $lhs_rhs_write; close $lhs_rhs_read; _do_parent( stdout_read => $stdout_read, stderr_read => $stderr_read, stdout_lines => ($stdout = []), stderr_lines => ($stderr = []), ); waitpid $lhs_pid, 0; waitpid $rhs_pid, 0; } elsif ( $lhs_pid ) { # right-hand-side child close $stdout_read; close $stderr_read; close $stderr_write; close $lhs_rhs_write; open STDIN, '<&', $lhs_rhs_read or die "Can't open: $!"; open STDOUT, '>&', $stdout_write or die "Can't open: $!"; close STDERR; exec @{$rhs_args}; } else { # left-hand side child close $stdout_read; close $stdout_write; close $lhs_rhs_read; close $stderr_read; open STDOUT, '>&', $lhs_rhs_write or die "Can't open: $!"; open STDERR, '>&', $stderr_write or die "Can't open: $!"; close STDIN; exec @{$lhs_args}; } return ($stdout,$stderr); } sub _do_parent { my %params = @_; my ( $stdout_read, $stderr_read, $stdout_lines, $stderr_lines ) = @params{qw/stdout_read stderr_read stdout_lines stderr_lines/}; while ( $stdout_read || $stderr_read ) { my $rin = ''; vec( $rin, fileno($stdout_read), 1 ) = 1 if $stdout_read; vec( $rin, fileno($stderr_read), 1 ) = 1 if $stderr_read; select( $rin, undef, undef, undef ); if ( $stdout_read && vec( $rin, fileno($stdout_read), 1 ) ) { my $line = <$stdout_read>; if ( defined( $line ) ) { push @{$stdout_lines}, $line; } else { close $stdout_read; undef $stdout_read; } } if ( $stderr_read && vec( $rin, fileno($stderr_read), 1 ) ) { my $line = <$stderr_read>; if ( defined( $line ) ) { push @{$stderr_lines}, $line; } else { close $stderr_read; undef $stderr_read; } } } chomp @{$stdout_lines}; chomp @{$stderr_lines}; return; } # Pipe into ack and return STDOUT and STDERR as array refs. sub pipe_into_ack_with_stderr { my $input = shift; my @args = @_; if ( ref($input) eq 'SCALAR' ) { # We could easily do this without temp files, but that would take # slightly more time than I'm willing to spend on this right now. my $tempfile = create_tempfile( ${$input} ); $input = $tempfile->filename; } return run_ack_with_stderr(@args, { # Use Perl since we don't know that 'cat' will exist. input => [caret_X(), '-pe1', $input], }); } # Pipe into ack and return STDOUT as array, for arguments see pipe_into_ack_with_stderr. sub pipe_into_ack { my ($stdout, undef) = pipe_into_ack_with_stderr( @_ ); return @{$stdout}; } # Use this one if order is important. sub lists_match { local $Test::Builder::Level = $Test::Builder::Level + 1; my @actual = @{+shift}; my @expected = @{+shift}; my $msg = _check_message( shift ); # Normalize all the paths for my $path ( @expected, @actual ) { $path = File::Next::reslash( $path ); } return subtest subtest_name( $msg ) => sub { plan tests => 1; my $ok; my $rc = eval 'use Test::Differences; 1;'; if ( $rc ) { $ok = eq_or_diff( [@actual], [@expected], $msg ); } else { $ok = is_deeply( [@actual], [@expected], $msg ); } if ( !$ok ) { diag( explain( actual => [@actual], expected => [@expected] ) ); } return $ok; }; } sub ack_lists_match { local $Test::Builder::Level = $Test::Builder::Level + 1; my $args = shift; my $expected = shift; my $msg = _check_message( shift ); my @args = @{$args}; return subtest subtest_name( $msg, @args ) => sub { plan tests => 2; my @results = run_ack( @args ); my $ok = lists_match( \@results, $expected, $msg ); return $ok; }; } # Use this one if you don't care about order of the lines. sub sets_match { local $Test::Builder::Level = $Test::Builder::Level + 1; my @actual = @{+shift}; my @expected = @{+shift}; my $msg = _check_message( shift ); return subtest subtest_name( $msg ) => sub { plan tests => 1; return lists_match( [sort @actual], [sort @expected], $msg ); }; } sub ack_sets_match { local $Test::Builder::Level = $Test::Builder::Level + 1; my $args = shift; my $expected = shift; my $msg = _check_message( shift ); my @args = @{$args}; return subtest subtest_name( $msg, @args ) => sub { plan tests => 2; my @results = run_ack( @args ); return sets_match( \@results, $expected, $msg ); }; } sub ack_error_matches { local $Test::Builder::Level = $Test::Builder::Level + 1; my $args = shift; my $expected = shift; my $msg = shift; return subtest subtest_name( $msg, $args, $expected ) => sub { plan tests => 4; my ( $stdout, $stderr ) = run_ack_with_stderr( @{$args} ); isnt( get_rc(), 0, 'Nonzero error' ); is_empty_array( $stdout, 'No normal output' ); is( scalar @{$stderr}, 1, 'Just one error' ); like( $stderr->[0], $expected, 'Error matches' ); }; } sub _record_option_coverage { my ( @command_line ) = @_; return unless $ENV{ACK_OPTION_COVERAGE}; return if $ENV{ACK_TEST_STANDALONE}; # We don't need to record the second time around. my $record_options = File::Spec->catfile( $orig_wd, 'dev', 'record-options' ); my $perl = caret_X(); if ( @command_line == 1 ) { my $command_line = $command_line[0]; # strip the command line up until 'ack' is found $command_line =~ s/^.*ack\b//; $command_line = "$perl $record_options $command_line"; system $command_line; } else { while ( @command_line && $command_line[0] !~ /ack/ ) { shift @command_line; } shift @command_line; # get rid of 'ack' itself unshift @command_line, $perl, $record_options; system @command_line; } return; } =head2 colorize( $big_long_string ) Turns a multi-line input string into its corresponding array of lines, with colorized transformations. <text> gets turned to filename color. {text} gets turned to line number color. (text) gets turned to highlight color. =cut sub colorize { my $input = shift; my @lines = line_split( $input ); for my $line ( @lines ) { # File name $line =~ s/<(.+?)>/Term::ANSIColor::colored($1, 'bold green')/eg; # Line number $line =~ s/\{(.+?)\}/Term::ANSIColor::colored($1, 'bold yellow')/eg; # Matches my $n; $n += $line =~ s/\((.+?)\)/Term::ANSIColor::colored($1, 'black on_yellow')/eg; $line .= "\e[0m\e[K" if $n; } return @lines; } BEGIN { my $has_io_pty = eval { require IO::Pty; 1; }; sub has_io_pty { return $has_io_pty; } if ($has_io_pty) { no strict 'refs'; # This function fools ack into thinking it is not writing to a pipe. This lets us test some of ack's default # behaviors, like defaulting to --break/--heading in interactive mode, but --nobreak/--noheading when writing # to a pipe. *run_ack_interactive = sub { my ( @args) = @_; my @cmd = build_ack_invocation(@args); @cmd = grep { ref ne 'HASH' } @cmd; _record_option_coverage(@cmd); @cmd = adjust_executable( @cmd ); my $pty = IO::Pty->new; my $pid = fork; if ( $pid ) { $pty->close_slave(); $pty->set_raw(); if ( wantarray ) { my @lines; while ( <$pty> ) { chomp; push @lines, $_; } close $pty; waitpid $pid, 0; return @lines; } else { my $output = ''; while ( <$pty> ) { $output .= $_; } close $pty; waitpid $pid, 0; return $output; } } else { $pty->make_slave_controlling_terminal(); my $slave = $pty->slave(); if ( -t *STDIN ) { # Is there something we can fall back on? Maybe re-opening /dev/console? $slave->clone_winsize_from(\*STDIN); } $slave->set_raw(); open STDIN, '<&', $slave->fileno() or die "Can't open: $!"; open STDOUT, '>&', $slave->fileno() or die "Can't open: $!"; open STDERR, '>&', $slave->fileno() or die "Can't open: $!"; close $slave; exec @cmd; } }; } else { no strict 'refs'; require Test::More; *run_ack_interactive = sub { local $Test::Builder::Level = $Test::Builder::Level + 1; Test::More::fail(<<'HERE'); Your system doesn't seem to have IO::Pty, and the developers forgot to check in this test file. Please file a bug report at https://github.com/beyondgrep/ack3/issues with the name of the file that generated this failure. HERE }; } } # This should not be treated as a complete list of the available # options, but it's complete enough to rely on until we find a # more elegant way to generate this list. sub get_expected_options { return ( '--ackrc', '--after-context', '--bar', '--before-context', '--break', '--cathy', '--color', '--color-filename', '--color-lineno', '--color-match', '--colour', '--column', '--context', '--count', '--create-ackrc', '--dump', '--env', '--files-from', '--files-with-matches', '--files-without-matches', '--filter', '--flush', '--follow', '--group', '--heading', '--help', '--help-types', '--help-colors', '--help-rgb-colors', '--ignore-ack-defaults', '--ignore-case', '--ignore-dir', '--ignore-directory', '--ignore-file', '--invert-match', '--literal', '--man', '--match', '--max-count', '--no-filename', '--no-recurse', '--nobreak', '--nocolor', '--nocolour', '--nocolumn', '--noenv', '--nofilter', '--nofollow', '--nogroup', '--noheading', '--noignore-dir', '--noignore-directory', '--nopager', '--nosmart-case', '--output', '--pager', '--passthru', '--print0', '--recurse', '--show-types', '--smart-case', '--sort-files', '--thpppt', '--type', '--type-add', '--type-del', '--type-set', '--version', '--with-filename', '--word-regexp', '-1', '-A', '-B', '-C', '-H', '-L', '-Q', '-R', '-S', '-c', '-f', '-g', '-h', '-i', '-l', '-m', '-n', '-o', '-r', '-s', '-v', '-w', '-x', ); } # This is just a handy diagnostic tool. sub _check_command_for_taintedness { my @args = @_; my @tainted = grep { tainted( $_ ) } @args; if ( @tainted ) { die "Can't execute this command because of taintedness:\nAll args: @args\nTainted: @tainted\n"; } return; } sub untaint { my ( $s ) = @_; $s =~ /\A(.*)\z/ or die 'Somehow unable to untaint'; return $1; } sub caret_X { return untaint( $^X ); # XXX How is it $^X can be tainted? We should not have to untaint it. } sub getcwd_clean { my $cwd = Cwd::getcwd(); $cwd =~ /./ or die 'cwd is empty'; return untaint( $cwd ); # XXX How is it that Cwd is tainted? } sub windows_slashify { my $str = shift; $str =~ s{/}{\\}g; return $str; } sub create_tempfile { my @lines = @_; my $tempfile = File::Temp->new(); print {$tempfile} join( "\n", @lines ); close $tempfile or die $!; return $tempfile; } sub touch { my $filename = shift; open my $fh, '>>', $filename or die "Unable to append to $filename: $!"; close $fh or die $!; return; } sub _check_message { my $msg = shift; if ( !defined( $msg ) ) { my (undef,undef,undef,$sub) = caller(1); die "You must pass a message to $sub"; } return $msg; } =head2 msg( [@args] ) Returns a basic diagnostic string based on the arguments passed in. It is not strictly accurate, like something from Data::Dumper, but is meant to balance accuracy of diagnostics with ease. msg( 'User codes', [ 'ABC', '123' ], undef, { foo => bar } ) will return 'User codes, [ABC, 123], undef, { foo => bar }' =cut sub msg { my @args = @_; my @disp; for my $i ( @args ) { if ( !defined($i) ) { push( @disp, 'undef' ); } elsif ( ref($i) eq 'HASH' ) { push( @disp, join( ', ', map { "$_=>" . ($i->{$_} // 'undef') } sort keys %{$i} ) ); } elsif ( ref($i) eq 'ARRAY' ) { push( @disp, '[' . join( ', ', map { $_ // 'undef' } @{$i} ) . ']' ); } else { push( @disp, "$i" ); } } return join( ', ', @disp ); } =head2 subtest_name( [@args] ) Returns a string for a name for a subtest, including the name of the subroutine and basic string representations of the arguments. This makes it easy for you to keep track of the important args passed into the test, and include the function name without repetitively typing it. sub test_whatever { my $user = shift; my $foo = shift; my $bar = shift; my $msg = shfit; return subtest subtest_name( $foo, $bar, $msg ) => sub { .... } test_whatever( 17, { this => 'that', other => undef }, 'Try it again without NYP' ); This will then give you TAP output like this: # Subtest: main::test_whatever( 17, {other=>undef, this=>that}, Try it again without NYP ) Note that in the example, we didn't pass C<$user> because it wasn't interesting to debugging. =cut sub subtest_name { my @args = @_; my (undef, undef, undef, $sub) = caller(1); ($sub ne '') or die 'subtest_name() can only be called inside a function'; return $sub unless @args; my $disp = msg( @args ); return "$sub( $disp )"; } # The tests blow up on Windows if the global files don't exist, # so here we create them if they don't, keeping track of the ones # we make so we can delete them later. my @created_global_files; sub create_globals { my @files; if ( is_windows() ) { require Win32; my @paths = map { File::Spec->catfile( Win32::GetFolderPath( $_ ), 'ackrc' ) } ( Win32::CSIDL_COMMON_APPDATA(), Win32::CSIDL_APPDATA() ); # Brute-force untaint the paths we built so they can be unlinked later. @files = map { /(.+)/ ? $1 : die } @paths; } else { @files = ( '/etc/ackrc' ); } if ( is_windows() || is_cygwin() ) { for my $filename ( @files ) { if ( not -e $filename ) { touch_ackrc( $filename ); push @created_global_files, $filename; } } } return @files; } sub clean_up_globals { foreach my $filename ( @created_global_files ) { unlink $filename or warn "Couldn't unlink $filename: $!"; } return; } sub touch_ackrc { my $filename = shift or die; write_file( $filename, () ); return; } sub safe_chdir { my $dir = shift; CORE::chdir( $dir ) or die "Can't chdir to $dir: $!"; return; } sub safe_mkdir { my $dir = shift; CORE::mkdir( $dir ) or die "Can't mkdir $dir: $!"; return; } sub filter_out_perldoc_noise { my $stderr = shift; # Don't worry if man complains about long lines, or if the terminal doesn't handle Unicode. $stderr = [ grep { !m{ can't\ break\ line | Wide\ character\ in\ print | Unknown\ escape\ E<0x[[:xdigit:]]+> | stdin\ isn't\ a\ terminal | Inappropriate\ ioctl\ for\ device }x } @{$stderr} ]; return $stderr; } sub make_unreadable { my $file = shift; my $old_mode; my $new_mode; my $error; # Change permissions of this file to unreadable. my @old_stat = stat($file); if ( !@old_stat ) { $error = "Unable to stat $file: $!"; } else { $old_mode = $old_stat[2]; my $nfiles = chmod 0000, $file; if ( !$nfiles ) { $error = "Unable to chmod $file: $!"; } else { my @new_stat = stat($file); if ( !@new_stat ) { $error = "Unable to stat $file after chmod: $!"; } else { $new_mode = $new_stat[2]; if ( $old_mode eq $new_mode ) { $error = "chmod did not modify modify ${file}'s permissions"; } elsif ( -r $file ) { $error = "File $file is still readable despite our attempts to changes its permissions"; } } } } return ($old_mode, $error); } sub adjust_executable { my @cmd = @_; my $perl = caret_X(); if ( $ENV{'ACK_TEST_STANDALONE'} ) { unshift( @cmd, $perl ); } else { unshift( @cmd, $perl, "-Mblib=$orig_wd" ); } return @cmd; } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-i.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000001347�14023027176�012540� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use Test::More tests => 9; use Util; use Barfly; prep_environment(); Barfly->run_tests( 't/ack-i.barfly' ); subtest 'Straight -i' => sub { plan tests => 4; my @expected = ( 't/swamp/groceries/fruit:1:apple', 't/swamp/groceries/junk:1:apple fritters', ); my @targets = map { "t/swamp/groceries/$_" } qw( fruit junk meat ); my @args = qw( --nocolor APPLE -i ); my @results = run_ack( @args, @targets ); lists_match( \@results, \@expected, '-i flag' ); @args = qw( --nocolor APPLE --ignore-case ); @results = run_ack( @args, @targets ); lists_match( \@results, \@expected, '--ignore-case flag' ); }; done_testing(); exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-underline.barfly�������������������������������������������������������������������0000644�0001751�0001751�00000001207�14023027176�015304� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# BEGIN comment here # # RUN # ack command line(s) # They should NOT be shell-escaped. Args are split on whitespace before # being passed in to ack. # # YESLINES # Lines that should match with underlines shown # ^^^^^^^^^^ # YES # Lines that should match, but without the underlines. # # NO # Lines that should not match. # # END # # Blank lines are always ignored. BEGIN Back-references RUN ack (\w+)-\1 ack (?:(\w+)-\1) YES Bamm-Bamm Ack-Ack foo-foo NO Bamm Bamm Bamm-Bam YESLINES Pebbles & Bamm-Bamm ^^^^^^^^^ ha-ha-ha-ha-ho-ho-hee-hee-hoo-hah ^^^^^ ^^^^^ ^^^^^ ^^^^^^^ END # vi:set ft=barfly: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-color.t����������������������������������������������������������������������������0000644�0001751�0001751�00000012536�14023027176�013430� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More; use lib 't'; use Util; plan tests => 15; prep_environment(); my $match = "\e[30;43m"; my $green_bold = "\e[1;32m"; my $yellow_bold = "\e[1;33m"; my $red = "\e[31m"; my $cyan = "\e[36m"; my $cyan_on_red = "\e[36;41m"; my $bold_white_on_green = "\e[1;37;42m"; my $blue_bold = "\e[1;34m"; my $color_end = "\e[0m"; my $line_end = "\e[0m\e[K"; NORMAL_COLOR: { my @files = qw( t/text/bill-of-rights.txt ); my @args = qw( free --color ); my @results = run_ack( @args, @files ); ok( grep { /\e/ } @results, 'normal match highlighted' ) or diag(explain(\@results)); } MATCH_WITH_BACKREF: { my @files = qw( t/text/bill-of-rights.txt ); my @args = qw( (free).*\1 --color ); my @results = run_ack( @args, @files ); is( @results, 1, 'backref pattern matches once' ); ok( grep { /\e/ } @results, 'match with backreference highlighted' ); } BRITISH_COLOR: { my @files = qw( t/text/bill-of-rights.txt ); my @args = qw( free --colour ); my @results = run_ack( @args, @files ); ok( grep { /\e/ } @results, 'normal match highlighted' ); } MULTIPLE_MATCHES: { my @files = qw( t/text/amontillado.txt ); my @args = qw( az.+?e|ser.+?nt -w --color ); my @results = run_ack( @args, @files ); is_deeply( \@results, [ "\"A huge human foot d'or, in a field ${match}azure${color_end}; the foot crushes a ${match}serpent${color_end}$line_end", ] ); } ADJACENT_CAPTURE_COLORING: { my @files = qw( t/text/raven.txt ); my @args = qw( (Temp)(ter) --color ); my @results = run_ack( @args, @files ); is_deeply( \@results, [ "Whether ${match}Tempter${color_end} sent, or whether tempest tossed thee here ashore,$line_end", ] ); } subtest 'Heading colors, single line' => sub { plan tests => 4; # Without the column number my $file = reslash( 't/text/ozymandias.txt' ); my @args = qw( mighty -i -w --color -H ); my @results = run_ack( @args, $file ); is_deeply( \@results, [ "${green_bold}$file${color_end}:${yellow_bold}11${color_end}:Look on my works, ye ${match}Mighty${color_end}, and despair!'$line_end", ] ); # With column number @results = run_ack( @args, '--column', $file ); is_deeply( \@results, [ "${green_bold}$file${color_end}:${yellow_bold}11${color_end}:${yellow_bold}22${color_end}:Look on my works, ye ${match}Mighty${color_end}, and despair!'$line_end", ] ); }; subtest 'Heading colors, grouped' => sub { plan tests => 4; # Without the column number my $file = reslash( 't/text/ozymandias.txt' ); my @args = qw( mighty -i -w --color --group ); my @results = run_ack( @args, 't/text' ); is_deeply( \@results, [ "${green_bold}$file${color_end}", "${yellow_bold}11${color_end}:Look on my works, ye ${match}Mighty${color_end}, and despair!'$line_end", ] ); # With column number @results = run_ack( @args, '--column', 't/text' ); is_deeply( \@results, [ "${green_bold}$file${color_end}", "${yellow_bold}11${color_end}:${yellow_bold}22${color_end}:Look on my works, ye ${match}Mighty${color_end}, and despair!'$line_end", ] ); }; subtest 'Passing args for colors' => sub { plan tests => 2; # Without the column number my $file = reslash( 't/text/ozymandias.txt' ); my @args = ( qw( mighty -i -w --color --group --column ), '--color-match=cyan on_red', '--color-filename=red', '--color-lineno=bold white on_green', '--color-colno=bold blue', ); my @results = run_ack( @args, 't/text' ); is_deeply( \@results, [ "${red}$file${color_end}", "${bold_white_on_green}11${color_end}:${blue_bold}22${color_end}:Look on my works, ye ${cyan_on_red}Mighty${color_end}, and despair!'$line_end", ] ); }; subtest 'Filename colors with count' => sub { if ( !has_io_pty() ) { plan skip_all => 'IO::Pty is required for this test'; return; } plan tests => 6; # Try it with default color. my $file = reslash('t/text/bill-of-rights.txt'); my $expected_with_color = "${green_bold}$file${color_end}:1"; my $expected_without_color = "$file:1"; my @args = qw( Congress --count --with-filename ); my @default_results = run_ack_interactive( @args, $file ); is_deeply( \@default_results, [$expected_with_color], 'Filename colored by default' ); # Now try it with red as the color. $expected_with_color = "${red}$file${color_end}:1"; @args = ( @args, '--color-filename=red' ); my @red_results = run_ack_interactive( @args, $file ); is_deeply( \@red_results, [$expected_with_color], 'Color is now red' ); # Now redirect our output and make sure the color doesn't come up. my @non_interactive_colorless_results = run_ack( @args, $file ); is_deeply( \@non_interactive_colorless_results, [$expected_without_color], "Filename not colored when output is redirected", ); # Now redirect output, but add --color explicitly. my @non_interactive_colored_results = run_ack( @args, '--color', $file ); is_deeply( \@non_interactive_colored_results, [$expected_with_color], "Filename colored when output is redirected and '--color' is used", ); }; done_testing(); exit 0; ������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-match.t����������������������������������������������������������������������������0000644�0001751�0001751�00000003577�14023027176�013413� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; use lib 't'; use Util; prep_environment(); my @tests = ( [ qw/Sue/ ], [ qw/boy -i/ ], # case-insensitive is handled correctly with --match [ qw/ll+ -Q/ ], # quotemeta is handled correctly with --match [ qw/gon -w/ ], # words is handled correctly with --match ); plan tests => @tests + 2; test_match( @{$_} ) for @tests; # Giving only the --match argument (and no other args) should not result in an error. run_ack( '--match', 'Sue' ); subtest 'Not giving a regex when piping into ack should result in an error' => sub { plan tests => 4; # Not giving a regex when piping into ack should result in an error. my ($stdout, $stderr) = pipe_into_ack_with_stderr( 't/text/amontillado.txt', '-t', 'perl' ); isnt( get_rc(), 0, 'ack should return an error when piped into without a regex' ); is_empty_array( $stdout, 'ack should return no STDOUT when piped into without a regex' ); cmp_ok( scalar @{$stderr}, '>', 0, 'Has to have at least one line of error message, but could have more under Appveyor' ); my $name = $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'ack'; is( $stderr->[0], "$name: No regular expression found.", 'Error message matches' ); }; done_testing(); exit 0; # Call ack normally and compare output to calling with --match regex. # # Due to 2 calls to run_ack, this sub runs altogether 3 tests. sub test_match { local $Test::Builder::Level = $Test::Builder::Level + 1; my $regex = shift; my @args = @_; push @args, '--sort-files'; return subtest subtest_name( @args ) => sub { my @files = ( 't/text' ); my @results_normal = run_ack( @args, $regex, @files ); my @results_match = run_ack( @args, @files, '--match', $regex ); return sets_match( \@results_normal, \@results_match, "Same output for regex '$regex'." ); }; } ���������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/illegal-regex.t������������������������������������������������������������������������0000644�0001751�0001751�00000002623�14023027176�014273� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; use lib 't'; use Util; plan tests => 2; prep_environment(); my $ACK = $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'ack'; # This unmatched paren is fatal. subtest 'Check fatal' => sub { plan tests => 2; my ($output,$stderr) = run_ack_with_stderr( '(set|get)_user_(id|(username)' ); my @expected = line_split( <<"HERE" ); $ACK: Invalid regex '(set|get)_user_(id|(username)' Regex: (set|get)_user_(id|(username) ^---HERE Unmatched ( in regex HERE is_empty_array( $output, 'No output' ); lists_match( $stderr, \@expected, 'Error body' ); }; # In Perl 5.20 and below, opening brace at the end doesn't get a warning. # In Perl 5.22 and above, we get a warning but the text changes. # This opening brace at the end is just a warning, but we still catch it in Perl > 5.20. subtest 'Check warning' => sub { if ( $^V < 5.022 ) { return pass( "Perl $^V does not throw a warning on the closing brace" ); } plan tests => 5; my ($output,$stderr) = run_ack_with_stderr( 'foo{' ); is_empty_array( $output, 'No output' ); is( $stderr->[0], "$ACK: Invalid regex 'foo{'", 'Line 1 OK' ); is( $stderr->[1], "Regex: foo{", 'Line 2 OK' ); like( $stderr->[2], qr/\Q^---HERE Unescaped left brace/, 'The message changes between Perl versions' ); is( scalar @{$stderr}, 3, 'Only 3 lines' ); }; exit 0; �������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/named-pipes.t��������������������������������������������������������������������������0000644�0001751�0001751�00000001701�14023027176�013750� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use lib 't'; use File::Temp; use Test::More; use Util; use POSIX (); MAIN: { local $SIG{'ALRM'} = sub { fail 'Timeout'; exit; }; prep_environment(); my $tempdir = File::Temp->newdir; safe_mkdir( "$tempdir/foo" ); my $rc = eval { POSIX::mkfifo( "$tempdir/foo/test.pipe", oct(660) ) }; if ( !$rc ) { dir_cleanup( $tempdir ); plan skip_all => $@ ? $@ : q{I can't run a mkfifo, so cannot run this test.}; } plan tests => 2; touch( "$tempdir/foo/bar.txt" ); alarm 5; # Should be plenty of time. my @results = run_ack( '-f', $tempdir ); is_deeply( \@results, [ "$tempdir/foo/bar.txt", ], 'Acking should not find the fifo' ); dir_cleanup( $tempdir ); done_testing(); } exit 0; sub dir_cleanup { my $tempdir = shift; unlink "$tempdir/foo/bar.txt"; rmdir "$tempdir/foo"; rmdir $tempdir; return; } ���������������������������������������������������������������ack-v3.5.0/t/ack-o.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000002362�14023027176�012544� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 2; use lib 't'; use Util; prep_environment(); NO_O: { my @files = qw( t/text/gettysburg.txt ); my @args = qw( the\\s+\\S+ ); my @expected = line_split( <<'HERE' ); but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who here dedicated to the great task remaining before us -- that from these the last full measure of devotion -- that we here highly resolve that shall have a new birth of freedom -- and that government of the people, by the people, for the people, shall not perish from the earth. HERE s/^\s+// for @expected; ack_lists_match( [ @args, @files ], \@expected, 'Find all the things without -o' ); } WITH_O: { my @files = qw( t/text/gettysburg.txt ); my @args = qw( the\\s+\\S+ -o ); my @expected = line_split( <<'HERE' ); the living, the unfinished the great the last the people, the people, the people, the earth. HERE s/^\s+// for @expected; ack_lists_match( [ @args, @files ], \@expected, 'Find all the things with -o' ); } done_testing(); exit 0; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-v.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000002126�14023027176�012551� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 2; use lib 't'; use Util; prep_environment(); NORMAL_CASE: { my @expected = line_split( <<'END' ); I met a traveller from an antique land Stand in the desert... Near them, on the sand, Which yet survive, stamped on these lifeless things, The hand that mocked them, and the heart that fed: 'My name is Ozymandias, king of kings: Nothing beside remains. Round the decay END my @args = qw( -v w ); my @files = qw( t/text/ozymandias.txt ); ack_lists_match( [ @args, @files ], \@expected, 'Find the lines that do not contain a "w"' ); } IGNORE_CASE: { my @expected = line_split( <<'END' ); I met a traveller from an antique land Stand in the desert... Near them, on the sand, The hand that mocked them, and the heart that fed: 'My name is Ozymandias, king of kings: Nothing beside remains. Round the decay END my @args = qw( -i -v w ); my @files = qw( t/text/ozymandias.txt ); ack_lists_match( [ @args, @files ], \@expected, 'Find the lines that do not contain a "w", ignoring case' ); } done_testing(); exit 0; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/Barfly.pm������������������������������������������������������������������������������0000644�0001751�0001751�00000010335�14023027176�013141� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package Barfly; use warnings; use strict; use Test::More; sub run_tests { my $class = shift; my $filename = shift; my $self = bless { blocks => [], }, $class; my $block; my $section; open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; my %blocknames_seen; my $lineno = 0; while ( my $line = <$fh> ) { ++$lineno; chomp $line; $line =~ s/\s*$//; next if $line =~ /^#/; next unless $line =~ /\S/; $line =~ s/\s+$//; if ( $line =~ /^BEGIN\s+(.*)/ ) { if ( defined($block) ) { die 'We are already in the middle of a block'; } my $blockname = $1; $blocknames_seen{ $blockname }++ and die qq{Block "$blockname" is duplicated in $filename at $lineno}; $block = Barfly::Block->new( $blockname, $filename, $lineno ); $section = undef; } elsif ( $line eq 'END' ) { push( @{$self->{blocks}}, $block ); $block = undef; $section = undef; } elsif ( $line eq 'RUN' || $line eq 'YES' || $line eq 'NO' || $line eq 'YESLINES' ) { $section = $line; } else { $block->add_line( $section, $line ); } } close $fh or die "Can't close $filename: $!"; my @blocks = @{$self->{blocks}} or return fail( "No blocks found in $filename!" ); for my $block ( @blocks ) { $block->run; } return; } package Barfly::Block; use Test::More; use Util; sub new { my $class = shift; my $label = shift // die 'Block label cannot be blank'; my $filename = shift; my $lineno = shift; return bless { label => $label, filename => $filename, lineno => $lineno, }, $class; } sub add_line { my $self = shift; my $section = shift; my $line = shift; push @{$self->{$section}}, $line; return; } sub run { local $Test::Builder::Level = $Test::Builder::Level + 1; my $self = shift; return subtest sprintf( '%s: %s, line %d', $self->{label}, $self->{filename}, $self->{lineno} ) => sub { plan tests => 2; my @command_lines = @{$self->{RUN} // []} or die 'No RUN lines specified!'; subtest "$self->{label}: YES/NO" => sub { plan tests => scalar @command_lines; # Set up scratch file my @yes = @{$self->{YES} // []}; my @no = @{$self->{NO} // []}; my $tempfile = create_tempfile( @yes, @no ); for my $command_line ( @command_lines ) { subtest $command_line => sub { plan tests => 2; $command_line = _untaint( $command_line ); my @args = split( / /, $command_line ); @args > 1 or die "Invalid command line: $command_line"; shift @args eq 'ack' or die 'Command line must begin with ack'; my @results = main::run_ack( @args, $tempfile->filename ); main::lists_match( \@results, \@yes, $command_line ); }; } }; subtest "$self->{label}: YESLINES" => sub { return pass( 'No yeslines' ) if !$self->{YESLINES}; plan tests => scalar @command_lines; my @all_lines = @{$self->{YESLINES}}; my @input_lines = grep { /[^ ^]/ } @all_lines; my $tempfile = create_tempfile( @input_lines ); for my $command_line ( @command_lines ) { subtest $command_line => sub { plan tests => 2; $command_line = _untaint( $command_line ); my @args = split( / /, $command_line ); @args > 1 or die "Invalid command line: $command_line"; shift @args eq 'ack' or die 'Command line must begin with ack'; push( @args, '--underline' ); my @results = main::run_ack( @args, $tempfile->filename ); main::lists_match( \@results, \@all_lines, $command_line ); }; } }; }; } sub _untaint { return $_[0] =~ /(.*)/ ? $1 : undef; } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/interactive.t��������������������������������������������������������������������������0000644�0001751�0001751�00000010377�14023027176�014074� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; use Term::ANSIColor qw(color); use lib 't'; use Util; if ( not has_io_pty() ) { plan skip_all => q{You need to install IO::Pty to run this test}; exit(0); } plan tests => 6; prep_environment(); INTERACTIVE_GROUPING_NOCOLOR: { my @args = qw( free --nocolor --sort-files ); my @files = qw( t/text ); my $output = run_ack_interactive(@args, @files); is( $output, <<'HERE' ); t/text/bill-of-rights.txt 4:or prohibiting the free exercise thereof; or abridging the freedom of 10:A well regulated Militia, being necessary to the security of a free State, t/text/constitution.txt 32:Number of free Persons, including those bound to Service for a Term t/text/gettysburg.txt 23:shall have a new birth of freedom -- and that government of the people, HERE } INTERACTIVE_NOHEADING_NOCOLOR: { my @args = qw( free --nocolor --noheading --sort-files ); # But will still default to --break my @files = qw( t/text ); my $output = run_ack_interactive(@args, @files); is( $output, <<'HERE' ); t/text/bill-of-rights.txt:4:or prohibiting the free exercise thereof; or abridging the freedom of t/text/bill-of-rights.txt:10:A well regulated Militia, being necessary to the security of a free State, t/text/constitution.txt:32:Number of free Persons, including those bound to Service for a Term t/text/gettysburg.txt:23:shall have a new birth of freedom -- and that government of the people, HERE } INTERACTIVE_NOGROUP_NOCOLOR: { my @args = qw( free --nocolor --nogroup --sort-files ); my @files = qw( t/text ); my $output = run_ack_interactive(@args, @files); is( $output, <<'HERE' ); t/text/bill-of-rights.txt:4:or prohibiting the free exercise thereof; or abridging the freedom of t/text/bill-of-rights.txt:10:A well regulated Militia, being necessary to the security of a free State, t/text/constitution.txt:32:Number of free Persons, including those bound to Service for a Term t/text/gettysburg.txt:23:shall have a new birth of freedom -- and that government of the people, HERE } INTERACTIVE_GROUPING_COLOR: { my @args = qw( free --sort-files ); # --color is on by default my @files = qw( t/text ); my $CFN = color 'bold green'; my $CRESET = color 'reset'; my $CLN = color 'bold yellow'; my $CM = color 'black on_yellow'; my $LINE_END = "\e[0m\e[K"; my @expected_lines = split( /\n/, <<"HERE" ); ${CFN}t/text/bill-of-rights.txt${CRESET} ${CLN}4${CRESET}:or prohibiting the ${CM}free${CRESET} exercise thereof; or abridging the ${CM}free${CRESET}dom of$LINE_END ${CLN}10${CRESET}:A well regulated Militia, being necessary to the security of a ${CM}free${CRESET} State,$LINE_END ${CFN}t/text/constitution.txt${CRESET} ${CLN}32${CRESET}:Number of ${CM}free${CRESET} Persons, including those bound to Service for a Term$LINE_END ${CFN}t/text/gettysburg.txt${CRESET} ${CLN}23${CRESET}:shall have a new birth of ${CM}free${CRESET}dom -- and that government of the people,$LINE_END HERE my @lines = run_ack_interactive(@args, @files); lists_match( \@lines, \@expected_lines, 'INTERACTIVE_GROUPING_COLOR' ); } INTERACTIVE_SINGLE_TARGET: { my @args = qw( (nevermore) -i --nocolor ); my @files = qw( t/text/raven.txt ); my $output = run_ack_interactive(@args, @files); is( $output, <<'HERE' ); Quoth the Raven, "Nevermore." With such name as "Nevermore." Then the bird said, "Nevermore." Of 'Never -- nevermore.' Meant in croaking "Nevermore." She shall press, ah, nevermore! Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Shall be lifted--nevermore! HERE } INTERACTIVE_NOCOLOR_REGEXP_CAPTURE: { my @args = qw( (nevermore) -i --nocolor ); my @files = qw( t/text/raven.txt ); my $output = run_ack_interactive(@args, @files); is( $output, <<'HERE' ); Quoth the Raven, "Nevermore." With such name as "Nevermore." Then the bird said, "Nevermore." Of 'Never -- nevermore.' Meant in croaking "Nevermore." She shall press, ah, nevermore! Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Quoth the Raven, "Nevermore." Shall be lifted--nevermore! HERE } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-l.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000004537�14023027176�012547� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; plan tests => 11; use lib 't'; use Util; prep_environment(); my @matching = qw( t/text/bill-of-rights.txt t/text/constitution.txt ); my @nonmatching = qw( t/text/amontillado.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt ); for my $arg ( qw( -l --files-with-matches ) ) { subtest "Files with matches: $arg" => sub { my @results = run_ack( $arg, 'strict', 't/text' ); sets_match( \@results, \@matching, 'File list match' ); } } for my $arg ( qw( -L --files-without-matches ) ) { subtest "Files without matches: $arg" => sub { my @results = run_ack( $arg, 'strict', 't/text' ); sets_match( \@results, \@nonmatching, 'File list match' ); } } DASH_L: { my @expected = qw( t/text/amontillado.txt t/text/gettysburg.txt t/text/raven.txt ); my @args = qw( God -i -l --sort-files ); my @files = qw( t/text ); ack_sets_match( [ @args, @files ], \@expected, 'Looking for God with -l' ); } DASH_CAPITAL_L: { my @expected = qw( t/text/bill-of-rights.txt t/text/constitution.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt ); my @switches = ( ['-L'], ['--files-without-matches'], ); for my $switches ( @switches ) { my @files = qw( t/text ); my @args = ( 'God', @{$switches}, '--sort-files' ); ack_sets_match( [ @args, @files ], \@expected, "Looking for God with @{$switches}" ); } } DASH_LV: { my @expected = qw( t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt ); my @switches = ( ['-l','-v'], ['-l','--invert-match'], ['--files-with-matches','-v'], ['--files-with-matches','--invert-match'], ); for my $switches ( @switches ) { my @files = qw( t/text ); my @args = ( 'religion', @{$switches}, '--sort-files' ); ack_sets_match( [ @args, @files ], \@expected, '-l -v will match all input files because "religion" will not be on every line' ); } } exit 0; �����������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-f.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000005403�14023027176�012532� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 6; use lib 't'; use Util; prep_environment(); DEFAULT_DIR_EXCLUSIONS: { my @expected = ( qw( t/swamp/0 t/swamp/c-header.h t/swamp/c-source.c t/swamp/constitution-100k.pl t/swamp/crystallography-weenies.f t/swamp/example.R t/swamp/file.bar t/swamp/file.foo t/swamp/fresh.css t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/meat t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/meat t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/meat t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/subdir/meat t/swamp/html.htm t/swamp/html.html t/swamp/incomplete-last-line.txt t/swamp/javascript.js t/swamp/lua-shebang-test t/swamp/Makefile t/swamp/Makefile.PL t/swamp/MasterPage.master t/swamp/notaMakefile t/swamp/notaRakefile t/swamp/notes.md t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/perl-test.t t/swamp/perl-without-extension t/swamp/perl.cgi t/swamp/perl.handler.pod t/swamp/perl.pl t/swamp/perl.pm t/swamp/perl.pod t/swamp/pipe-stress-freaks.F t/swamp/Rakefile t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/sample.asp t/swamp/sample.aspx t/swamp/sample.rake t/swamp/service.svc t/swamp/stuff.cmake t/swamp/CMakeLists.txt t/swamp/swamp/ignoreme.txt ), 't/swamp/not-an-#emacs-workfile#', ); my @args = qw( -f t/swamp ); ack_sets_match( [ @args ], \@expected, 'DEFAULT_DIR_EXCLUSIONS' ); is( get_rc(), 0, '-f with matches exits with 0' ); } COMBINED_FILTERS: { my @expected = qw( t/swamp/0 t/swamp/constitution-100k.pl t/swamp/perl.pm t/swamp/Rakefile t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/perl-without-extension t/swamp/perl.cgi t/swamp/Makefile.PL t/swamp/perl-test.t t/swamp/perl.handler.pod t/swamp/perl.pl t/swamp/perl.pod ); my @args = qw( -f t/swamp -t perl -t rake ); ack_sets_match( [ @args ], \@expected, 'COMBINED_FILTERS' ); is( get_rc(), 0, '-f with matches exits with 0' ); } EXIT_CODE: { my @expected; my @args = qw( -f t/swamp --type-add=baz:ext:baz -t baz ); ack_sets_match( \@args, \@expected, 'EXIT_CODE' ); is( get_rc(), 1, '-f with no matches exits with 1' ); } done_testing(); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/prescan-line-boundaries.t��������������������������������������������������������������0000644�0001751�0001751�00000000540�14023027176�016257� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # https://github.com/beyondgrep/ack2/issues/571 use strict; use warnings; use lib 't'; use Test::More tests => 2; use Util; prep_environment(); my $tempfile = create_tempfile( <<'HERE' ); fo oo HERE my @results = run_ack('-l', 'fo\s+oo', $tempfile->filename); is_empty_array( \@results, '\s+ should never match across line boundaries' ); ����������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-print0.t���������������������������������������������������������������������������0000644�0001751�0001751�00000004614�14023027176�013524� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 15; use lib 't'; use Util; prep_environment(); G_NO_PRINT0: { my @expected = qw( t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/ozymandias.txt ); my $filename_regex = 'i'; my @files = qw( t/text/ ); my @args = ( '-g', $filename_regex ); my @results = run_ack( @args, @files ); sets_match( \@results, \@expected, 'Files found with -g and without --print0' ); is_empty_array( [ grep { /\0/ } @results ], ' ... no null byte in output' ); } G_PRINT0: { my $expected = join( "\0", map { reslash($_) } qw( t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/ozymandias.txt ) ) . "\0"; # string of filenames separated and concluded with null byte my $filename_regex = 'i'; my @files = qw( t/text ); my @args = ( '-g', $filename_regex, '--sort-files', '--print0' ); my @results = run_ack( @args, @files ); is_deeply( \@results, [$expected], 'Files found with -g and with --print0' ); } F_PRINT0: { my @files = qw( t/text/ ); my @args = qw( -f --print0 ); my @results = run_ack( @args, @files ); # Checking for exact files is fragile, so just see whether we have \0 in output. is( scalar @results, 1, 'Only one line of output with -f and --print0' ); is_nonempty_array( [ grep { /\0/ } @results ], ' ... and null bytes in output' ); } L_PRINT0: { my $regex = 'of'; my @files = qw( t/text/ ); my @args = ( '-l', '--print0', $regex ); my @results = run_ack( @args, @files ); # Checking for exact files is fragile, so just see whether we have \0 in output. is( scalar @results, 1, 'Only one line of output with -l and --print0' ); is_nonempty_array( [ grep { /\0/ } @results ], ' ... and null bytes in output' ); } COUNT_PRINT0: { my $regex = 'of'; my @files = qw( t/text/ ); my @args = ( '--count', '--print0', $regex ); my @results = run_ack( @args, @files ); # Checking for exact files is fragile, so just see whether we have \0 in output. is( scalar @results, 1, 'Only one line of output with --count and --print0' ); is_nonempty_array( [ grep { /\0/ } @results ], ' ... and null bytes in output' ); is_nonempty_array( [ grep { /:\d+/ } @results ], ' ... and ":\d+" in output, so the counting also works' ); } ��������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-Q.t��������������������������������������������������������������������������������0000644�0001751�0001751�00000004313�14023027176�012504� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More; plan tests => 3; use lib 't'; use Util; prep_environment(); my $ACK = $ENV{ACK_TEST_STANDALONE} ? 'ack-standalone' : 'ack'; # The unquoted "+" in "svn+ssh" will make the match fail. subtest 'Plus sign' => sub { plan tests => 3; my @args = qw( svn+ssh t/swamp ); ack_lists_match( [ @args ], [], 'No matches without the -Q' ); my $target = reslash( 't/swamp/Rakefile' ); my @expected = line_split( <<"HERE" ); $target:44: baseurl = "svn+ssh:/#{ENV['USER']}\@rubyforge.org/var/svn/#{PKG_NAME}" $target:50: baseurl = "svn+ssh:/#{ENV['USER']}\@rubyforge.org/var/svn/#{PKG_NAME}" HERE for my $arg ( qw( -Q --literal ) ) { ack_lists_match( [ @args, $arg ], \@expected, "$arg should make svn+ssh finable" ); } }; subtest 'Square brackets' => sub { plan tests => 4; my @args = qw( [ack] t/swamp ); my @results = run_ack( @args ); cmp_ok( scalar @results, '>', 100, 'Without quoting, the [ack] returns many matches' ); my $target = reslash( 't/swamp/Makefile' ); my @expected = line_split( <<"HERE" ); $target:15:# EXE_FILES => [q[ack]] $target:17:# NAME => q[ack] HERE for my $arg ( qw( -Q --literal ) ) { ack_lists_match( [ @args, $arg ], \@expected, "$arg should make svn+ssh finable" ); } }; subtest 'Patterns that would be invalid if not -Q' => sub { plan tests => 21; my %problems = ( '*' => 'Quantifier follows nothing in regex', '[' => 'Unmatched [ in regex', '(' => 'Unmatched ( in regex', ); while ( my ($problem, $explanation) = each %problems ) { my ($output,$stderr) = run_ack_with_stderr( $problem ); is_empty_array( $output, 'No output' ); is( $stderr->[0], "$ACK: Invalid regex '$problem'", 'Line 1 OK' ); is( $stderr->[1], "Regex: $problem", 'Line 2 OK' ); like( $stderr->[2], qr/\Q^---HERE $explanation/, 'Does the explanation match?' ); is( scalar @{$stderr}, 3, 'Only 3 lines' ); } for my $problem ( keys %problems ) { my @results = run_ack( '-Q', $problem ); cmp_ok( scalar @results, '>', 100, 'When we quote, all is happy and we get lots of results' ); } }; exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/highlighting.t�������������������������������������������������������������������������0000644�0001751�0001751�00000005165�14023027176�014223� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 6; use lib 't'; use Util; prep_environment(); my @HIGHLIGHT = qw( --color --group --sort-files ); BASIC: { my @args = qw( --sort-files Montresor t/text/ ); my $expected_original = <<'END'; <t/text/amontillado.txt> {99}:the catacombs of the (Montresor)s. {152}:"The (Montresor)s," I replied, "were a great and numerous family." {309}:"For the love of God, (Montresor)!" END $expected_original = windows_slashify( $expected_original ) if is_windows; my @expected = colorize( $expected_original ); my @results = run_ack( @args, @HIGHLIGHT ); is_deeply( \@results, \@expected, 'Basic highlights match' ); } METACHARACTERS: { my @args = qw( --sort-files \w*rave\w* t/text/ ); my $expected_original = <<'END'; <t/text/gettysburg.txt> {13}:we can not hallow -- this ground. The (brave) men, living and dead, who <t/text/ozymandias.txt> {1}:I met a (traveller) from an antique land <t/text/raven.txt> {51}:By the (grave) and stern decorum of the countenance it wore, {52}:"Though thy crest be shorn and shaven, thou," I said, "art sure no (craven), END $expected_original = windows_slashify( $expected_original ) if is_windows; my @expected = colorize( $expected_original ); my @results = run_ack( @args, @HIGHLIGHT ); is_deeply( \@results, \@expected, 'Metacharacters match' ); } CONTEXT: { my @args = qw( --sort-files free -C1 t/text/ ); my $expected_original = <<'END'; <t/text/bill-of-rights.txt> {3}-Congress shall make no law respecting an establishment of religion, {4}:or prohibiting the (free) exercise thereof; or abridging the (free)dom of {5}-speech, or of the press; or the right of the people peaceably to assemble, -- {9}- {10}:A well regulated Militia, being necessary to the security of a (free) State, {11}-the right of the people to keep and bear Arms, shall not be infringed. <t/text/constitution.txt> {31}-respective Numbers, which shall be determined by adding to the whole {32}:Number of (free) Persons, including those bound to Service for a Term {33}-of Years, and excluding Indians not taxed, three fifths of all other <t/text/gettysburg.txt> {22}-these dead shall not have died in vain -- that this nation, under God, {23}:shall have a new birth of (free)dom -- and that government of the people, {24}-by the people, for the people, shall not perish from the earth. END $expected_original = windows_slashify( $expected_original ) if is_windows; my @expected = colorize( $expected_original ); my @results = run_ack( @args, @HIGHLIGHT ); is_deeply( \@results, \@expected, 'Context is all good' ); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-ignore-file.t����������������������������������������������������������������������0000644�0001751�0001751�00000005106�14023027176�014505� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use strict; use warnings; use Test::More tests => 3; use lib 't'; use Util; prep_environment(); my @all = qw( t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/meat t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/meat t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/meat t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/subdir/meat ); my @meat = grep { /meat/ } @all; my @junk = grep { /junk/ } @all; subtest 'is:xxx matching' => sub { plan tests => 5; ack_sets_match( [qw( -f t/swamp/groceries )], [ @all ], 'Unfiltered' ); ack_sets_match( [qw( -f t/swamp/groceries --ignore-file=is:fruit )], [ @meat, @junk ], 'Ignoring fruit with is' ); ack_sets_match( [qw( -f t/swamp/groceries --ignore-file=is:bongo )], [ @all ], 'Ignoring with is that does not match' ); ack_sets_match( [qw( -f t/swamp/groceries --ignore-file=is:subdir )], [ @all ], '--ignore-file only operatoes on filenames, not dirnames' ); ack_sets_match( [qw( -f t/swamp/groceries --ignore-file=is:fruit --ignore-file=is:junk )], [ @meat ], 'Multiple is arguments' ); }; subtest 'match:xxx matching' => sub { plan tests => 6; # The match is case-insensitive, unaffected by -i or -I. for my $u ( 'u', 'U' ) { for my $I ( '-i', '-I', undef ) { my @args = ( qw( -f t/swamp/groceries ), "--ignore-file=match:$u" ); push( @args, $I ) if defined $I; ack_sets_match( [ @args ], [ @meat ], 'Should only match files with do not have "u" in them: ' . join( ' ', map { $_ // 'undef' } @args ) ); } } }; subtest 'Invalid invocation' => sub { plan tests => 8; my @bad_args = ( '--ignore-file=foo', '--ignore-file=foo:bar', ); for my $bad_arg ( @bad_args ) { my ( $man_output, $man_stderr ) = run_ack_with_stderr( $bad_arg ); is_empty_array( $man_output, "No output for $bad_arg" ); is( scalar @{$man_stderr}, 2, "Exactly two errors for $bad_arg" ); like( $man_stderr->[0], qr/ack(?:-standalone)?: Unknown filter type 'foo'. Type must be one of: ext, firstlinematch, is, match./ ); like( $man_stderr->[1], qr/ack(?:-standalone)?: Invalid option on command line/ ); } }; done_testing(); exit 0; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/multiple-captures.t��������������������������������������������������������������������0000644�0001751�0001751�00000000550�14023027176�015226� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl # Multiple capture groups used to confuse ack. # https://github.com/beyondgrep/ack2/issues/244 use strict; use warnings; use Test::More; use lib 't'; use Util; plan tests => 2; prep_environment(); my ( $stdout, $stderr ) = run_ack_with_stderr('--color', '(foo)|(bar)', 't/swamp'); is_nonempty_array( $stdout ); is_empty_array( $stderr ); exit 0; ��������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-passthru.t�������������������������������������������������������������������������0000644�0001751�0001751�00000012077�14023027176�014163� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 6; use lib 't'; use Util; prep_environment(); my @full_speech = <DATA>; chomp @full_speech; my @johnny_rebeck = read_file( 't/range/johnny-rebeck.txt' ); chomp @johnny_rebeck; subtest 'Gettysburg without --passthru' => sub { plan tests => 2; my @expected = line_split( <<'HERE' ); Now we are engaged in a great civil war, testing whether that nation, on a great battle-field of that war. We have come to dedicate a portion HERE @expected = color_match( qr/war/, @expected ); my @files = qw( t/text/gettysburg.txt ); my @args = qw( war --color ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Search for war' ); }; subtest 'Gettysburg with --passthru' => sub { plan tests => 2; my @expected = color_match( qr/war/, @full_speech ); my @files = qw( t/text/gettysburg.txt ); my @args = qw( war --passthru --color ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, q{Still lookin' for war, in passthru mode} ); }; subtest '--passthru with/without ranges' => sub { plan tests => 4; my @args = qw( Rebeck --passthru --color t/range/johnny-rebeck.txt ); my @expected = color_match( qr/Rebeck/, @johnny_rebeck ); my @results = run_ack( @args ); lists_match( \@results, \@expected, q{Searching without a range} ); my @range_expected; my $nmatches = 0; for my $line ( @johnny_rebeck ) { if ( $line =~ /Rebeck/ ) { ++$nmatches; if ( $nmatches == 2 || $nmatches == 3 ) { ($line) = color_match( qr/Rebeck/, $line ); } } push( @range_expected, $line ); } @results = run_ack( @args, '--range-start=CHORUS', '--range-end=VERSE' ); lists_match( \@results, \@range_expected, q{Searching with a range} ); }; # This tests the filename/lineno separators. subtest 'With filename' => sub { plan tests => 2; my $ozy = reslash( 't/text/ozymandias.txt' ); my @expected = line_split( <<"HERE" ); $ozy-1-I met a traveller from an antique land $ozy-2-Who said: Two vast and trunkless legs of stone $ozy-3-Stand in the desert... Near them, on the sand, $ozy:4:Half sunk, a shattered visage lies, whose frown, $ozy:5:And wrinkled lip, and sneer of cold command, $ozy-6-Tell that its sculptor well those passions read $ozy:7:Which yet survive, stamped on these lifeless things, $ozy-8-The hand that mocked them, and the heart that fed: $ozy-9-And on the pedestal these words appear: $ozy-10-'My name is Ozymandias, king of kings: $ozy-11-Look on my works, ye Mighty, and despair!' $ozy-12-Nothing beside remains. Round the decay $ozy-13-Of that colossal wreck, boundless and bare $ozy-14-The lone and level sands stretch far away. HERE my @results = run_ack( qw( li\w+ t/text/ozymandias.txt -H --passthru ) ); lists_match( \@results, \@expected, q{With filename} ); }; SKIP: { skip 'Input options have not been implemented for Win32 yet', 2 if is_windows(); # Some lines will match, most won't. my @ack_args = qw( war --passthru --color ); my @results = pipe_into_ack( 't/text/gettysburg.txt', @ack_args ); is( scalar @results, scalar @full_speech, 'Got all the lines back' ); my @escaped_lines = grep { /\e/ } @results; is( scalar @escaped_lines, 2, 'Only two lines are highlighted' ); } done_testing(); exit 0; sub color_match { my $re = shift; my @lines = @_; for my $line ( @lines ) { if ( $line =~ /$re/ ) { $line =~ s/($re)/\e[30;43m$1\e[0m/g; $line .= "\e[0m\e[K"; } } return @lines; } __DATA__ Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate -- we can not consecrate -- we can not hallow -- this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us -- that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion -- that we here highly resolve that these dead shall not have died in vain -- that this nation, under God, shall have a new birth of freedom -- and that government of the people, by the people, for the people, shall not perish from the earth. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/t/ack-output.t���������������������������������������������������������������������������0000644�0001751�0001751�00000023263�14023027176�013651� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!perl use warnings; use strict; use Test::More tests => 46; use lib 't'; use Util; prep_environment(); DOLLAR_1: { my @files = qw( t/text/ ); my @args = qw/ --output=x$1x free(\\S+) --sort-files /; my @target_file = map { reslash($_) } qw( t/text/bill-of-rights.txt t/text/gettysburg.txt ); my @expected = ( "$target_file[0]:4:xdomx", "$target_file[1]:23:xdomx", ); ack_sets_match( [ @args, @files ], \@expected, 'Find all the things with --output function' ); } DOLLAR_UNDERSCORE: { my @expected = line_split( <<'HERE' ); shall have a new birth of freedom -- and that government of the people,xshall have a new birth of freedom -- and that government of the people, HERE my @files = qw( t/text/gettysburg.txt ); my @args = qw( free --output=$_x$_ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Matching line' ); } ARG_MULTIPLE_FILES: { # Note the first line is there twice because it matches twice. my @expected = line_split( <<'HERE' ); or prohibiting the free exercise thereof; or abridging the freedom of or prohibiting the free exercise thereof; or abridging the freedom of A well regulated Militia, being necessary to the security of a free State, Number of free Persons, including those bound to Service for a Term shall have a new birth of freedom -- and that government of the people, HERE my @files = qw( t/text ); my @args = qw( free --sort-files -h --output=$_ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Matching line' ); } # Find a match in multiple files, and output it in double quotes. DOUBLE_QUOTES: { my @files = qw( t/text/ ); my @args = ( '--output="$1"', '(free\\w*)', '--sort-files' ); my @target_file = map { reslash($_) } qw( t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt ); my @expected = ( qq{$target_file[0]:4:"free"}, qq{$target_file[0]:4:"freedom"}, qq{$target_file[0]:10:"free"}, qq{$target_file[1]:32:"free"}, qq{$target_file[2]:23:"freedom"}, ); ack_sets_match( [ @args, @files ], \@expected, 'Find all the things with --output function' ); } MATCH: { my @expected = ( 'free' ); my @files = qw( t/text/gettysburg.txt ); my @args = qw( free --output=$& ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line matching pattern' ); } MATCH_MULTIPLE_FILES: { my @expected = line_split( <<'HERE' ); t/text/bill-of-rights.txt:4:free t/text/bill-of-rights.txt:4:free t/text/bill-of-rights.txt:10:free t/text/constitution.txt:32:free t/text/gettysburg.txt:23:free HERE my @files = qw ( t/text ); my @args = qw( free --sort-files --output=$& ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line matching pattern' ); } PREMATCH: { # No HEREDOC here since we do not want our editor/IDE messing with trailing whitespace. my @expected = ( 'shall have a new birth of ' ); my @files = qw( t/text/gettysburg.txt ); my @args = qw( freedom --output=$` ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line preceding match' ); } PREMATCH_MULTIPLE_FILES: { # No HEREDOC here since we do not want our editor/IDE messing with trailing whitespace. my @expected = ( 'or prohibiting the free exercise thereof; or abridging the ', 'shall have a new birth of ' ); my @files = qw( t/text/); my @args = qw( freedom -h --sort-files --output=$` ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line preceding match' ); } POSTMATCH: { my @expected = split( /\n/, <<'HERE' ); -- and that government of the people, HERE my @files = qw( t/text/gettysburg.txt ); my @args = qw( freedom --output=$' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line that follows match' ); } POSTMATCH_MULTIPLE_FILES: { my @expected = line_split( <<'HERE' ); of -- and that government of the people, HERE my @files = qw( t/text/ ); my @args = qw( freedom -h --sort-files --output=$' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Part of a line that follows match' ); } SUBPATTERN_MATCH: { my @expected = ( 'love-God-Montresor' ); my @files = qw( t/text/amontillado.txt ); my @args = qw( (love).+(God).+(Montresor) --output=$1-$2-$3 ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Capturing parentheses match' ); } SUBPATTERN_MATCH_MULTIPLE_FILES: { my @expected = line_split( <<'HERE' ); the-free-exercise a-free-State of-free-Persons HERE my @files = qw( t/text/ ); my @args = qw( (\w+)\s(free)\s(\w+) -h --sort-files --output=$1-$2-$3 ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Capturing parentheses match' ); } INPUT_LINE_NUMBER: { my @expected = ( 'line:15' ); my @files = qw( t/text/bill-of-rights.txt ); my @args = qw( quartered --output=line:$. ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Line number' ); } INPUT_LINE_NUMBER_MULTIPLE_FILES: { my @expected = line_split( <<'HERE' ); t/text/bill-of-rights.txt:4:line:4 t/text/bill-of-rights.txt:4:line:4 t/text/bill-of-rights.txt:10:line:10 t/text/constitution.txt:32:line:32 t/text/gettysburg.txt:23:line:23 HERE my @files = qw( t/text/ ); my @args = qw( free --sort-files --output=line:$. ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Line number' ); } LAST_PAREN_MATCH: { my @expected = line_split( <<'HERE' ); t/text/amontillado.txt:124:love t/text/amontillado.txt:309:love t/text/amontillado.txt:311:love t/text/constitution.txt:267:hate HERE my @files = qw( t/text/ ); my @args = qw( (love)|(hate) --sort-files --output=$+ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Last paren match' ); } COMBOS_1: { my @expected = line_split( <<'HERE' ); t/text/amontillado.txt:124:love-124-d; you are happy, t/text/amontillado.txt:309:love-309- of God, Montresor!" t/text/amontillado.txt:311:love-311- of God!" t/text/constitution.txt:267:hate-267-ver, from any King, Prince, or foreign State. HERE my @files = qw( t/text/ ); my @args = qw( (love)|(hate) --sort-files --output=$+-$.-$' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Combos 1' ); } COMBOS_2: { my @expected = line_split( <<'HERE' ); t/text/amontillado.txt:124:happy-happy-happy t/text/raven.txt:73:happy-happy-happy HERE my @files = qw( t/text/ ); my @args = qw( (happy) --sort-files -i --output=$1-$&-$1 ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Combos 2' ); } COMBOS_3: { my @expected = line_split( <<'HERE' ); t/text/amontillado.txt:124:precious. You are rich, respected, admired, beloved; you are ---,--happy t/text/raven.txt:73:Caught from some un--- master whom unmerciful Disaster--happy HERE my @files = qw( t/text/ ); my @args = qw( (happy) --sort-files -i --output=$`---$'--$+ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Combos 2' ); } NUMERIC_SUBSTITUTIONS: { # Make sure that substitutions don't affect future substitutions. my @expected = line_split( <<'HERE' ); t/text/constitution.txt:269:Section 10 on line 269 HERE my @files = qw( t/text/bill-of-rights.txt t/text/constitution.txt ); my @args = ( '(\d\d)', '--output=Section $1 on line $.' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Numeric substitutions' ); } CHARACTER_SUBSTITUTIONS: { # Make sure that substitutions don't affect future substitutions. my @expected = line_split( <<"HERE" ); t/text/bill-of-rights.txt:15:No Soldier shall, in time of peace be in any house, without\tin any house, without HERE my @files = qw( t/text/ ); my @args = ( '\s+quartered\s+(.+)', '--output=$`\n$1\t$1' ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Character substitutions' ); } # $f is the filenname, needed for grep, emulating ack2 $filename:$lineno:$_ FILENAME_SUBSTITUTION_1 : { my @expected = line_split( <<'HERE' ); t/text/ozymandias.txt:4:Half sunk, a shattered visage lies, whose frown, HERE my @files = qw( t/text/ozymandias.txt ); my @args = qw( visage --output=$f:$.:$_ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Filename with matching line' ); } FILENAME_SUBSTITUTION_2 : { my @expected = line_split( <<'HERE' ); t/text/ozymandias.txt:4:visage HERE my @files = qw( t/text/ozymandias.txt ); my @args = qw( visage --output=$f:$.:$& ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Filename with match' ); } FILENAME_SUBSTITUTION_3 : { my @expected = line_split( <<'HERE' ); t/text/ozymandias.txt:4:visage HERE my @files = qw( t/text/ozymandias.txt ); my @args = qw( (visage) --output=$f:$.:$+ ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Filename with last match' ); } NO_SPECIALS_IN_OUTPUT_EXPRESSION : { my @expected = line_split( <<'HERE' ); literal literal HERE my @files = qw( t/text/ozymandias.txt ); my @args = qw( sand --output=literal ); my @results = run_ack( @args, @files ); lists_match( \@results, \@expected, 'Filename with last match' ); } done_testing(); exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/Changes����������������������������������������������������������������������������������0000644�0001751�0001751�00000026721�14023040515�012412� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������History file for ack 3. https://beyondgrep.com/ v3.5.0 Fri Mar 12 22:29:44 CST 2021 ======================================== [FIXES] Reworked the option parsing to run correctly with Getopt::Long 2.38. [FEATURES] Added support for the Elm language. (GH#316) Added support for the Purescript language. (GH#317) Added support for the Bazel build tool. (GH#327) v3.4.0 Mon Jun 29 23:04:18 CDT 2020 ======================================== [FEATURES] When calling "ack -c" to get a list of filenames and counts, the filename would not be colored like when getting normal search results. Now it will. Thanks to Matthew Hughes for adding the feature, and Ophir Lifshitz for the suggestion. (GH#282) Added --toml for the TOML filetype. (GH#306) [FIXES] The test t/ack-x.t would fail when run as root. Now it is skipped. Thanks, Michael LaGrasta. (GH#217) v3.3.1 Mon Jan 13 10:27:16 CST 2020 ======================================== [FIXES] Some regexes would be shown as invalid when used with the -Q option. Since the -Q tells ack to treat the regex as a literal, this shouldn't be possible. (GH#294) v3.3.0 Sat Dec 28 16:00:21 CST 2019 ======================================== [FEATURES] The error message ack displays when the regex passed is invalid has been improved. The message is more readable and includes a pointer to the offending part of the regex. For example: $ ack 'status: (open|closed|in progress' ack: Invalid regex 'status: (open|closed|in progress' Regex: status: (open|closed|in progress ^---HERE Unmatched ( in regex Added many new file and directory exclusions to speed up file selection. * Python's *.pyc, *.pyd and *.pyo compiled files * Python's __pycache__ and .pytest_cache directories * Linux *.so shared object files * Windows dynamic-link library *.dll files * gettext compiled *.mo translation files * macOS's __MACOSX directories and .DS_Store files Reorganized the --help menu to put "action" options like -f, -g and -l at the top of the listing. The --show-types option only has an effect with -f or -g. ack will now tell you if you use --show-types without -f or -g when it will have no effect. Improved the error message when ack gets passed two options that can't be used together. [FIXES] Fixed the behavior of --break and --heading. Using --break would implicitly set --noheading, and --heading would implicitly set --nobreak. The following pairs of options don't make sense to use together, and ack will now warn you if you try: * -x and --files-from * -v and -o * -v and --output * -v and --passthru Fixed the minimum version of the Getopt::Long module required. (GH #287) The line number and filename separators in --passthru mode now work the same as in context (-A/-B/-C) mode. (GH #291) v3.2.0 Sun Nov 3 22:52:18 CST 2019 ======================================== [FEATURES] Added "-t X" as a short alias for --type=X. Added "-T X" as a short alias for --type=noX. The feature of using the name of the type as an option is deprecated. For example, ack currently lets you use "--perl" instead of "--type=perl" or "-t perl", This is now deprecated and will be removed in a future release. Removed support for Parrot (--parrot). v3.1.3 Sat Oct 19 19:23:48 CDT 2019 ======================================== No changes to functionality. Fixed a problem with version numbers. Thanks to Dan Book for his help. See https://github.com/beyondgrep/ack3/commit/b3c43d44109dea6ebc0753107a8e85a6b322f4ca v3.1.2 Mon Oct 14 21:47:51 CDT 2019 ======================================== [SPEEDUP] Using -w with a pattern that ended with a metacharacter would be slower than it should be because it would skip an optimization. Now it's fixed. (GH #181, #251) [FIXES] Fixed test failures that would sometimes happen on Windows machines because of taint mode. Thanks, Tomasz Konojacki. (GH #235) Remove the use of the version.pm module. v3.1.1 Sat Aug 31 22:56:10 CDT 2019 ======================================== [SPEEDUP] Improved the speed up the -l, -L and -c options by pre-scanning the file in bulk before doing line-by-line scan. (GH #221) ack now uses File::Next 1.18 which calls stat() only once per file or directory, instead of sometimes calling it twice. This should improve the time spent traversing directories. [FIXES] On Windows, patterns with $ to mark the end of the line would not match. (GH #229) [DOCUMENTATION] Fixed docs that referred to --range-stop instead of --range-end. (GH #228) v3.1.0 Thu Aug 22 22:43:15 CDT 2019 ======================================== [FEATURES] Added the --range-start and --range-end options to allow searching only ranges of each file. (GH #165) v3.0.3 Tue Aug 20 23:42:02 CDT 2019 ======================================== [FIXES] Made smartcase's check for lowercase patterns smarter. [DOCUMENTATION] Updated many URLs, especially in the config. (GH #223) v3.0.2 Thu Jul 4 21:42:43 CDT 2019 ======================================== [FIXES] ack's smart-case feature would think that a pattern like "select \S+ from" is looking for a uppercase letter, and so would not make a case-insensitive search. Now, ack knows that uppercase letters in metacharacters don't count as looking for a uppercase letter. (GH #156, 187, 214) v3.0.1 Tue Jun 25 20:47:58 CDT 2019 ======================================== [FIXES] The -s option tells ack not to complain about missing or unreadable files it tries to search. The -s option would not always work in conjection with the -x option. Now it does. Thanks, Anders Eriksson and M. Scott Ford. (GH #175) ack would die if you specified a --output option that didn't use one of Perl's special match variables. Now it won't. Thanks, M. Scott Ford. (GH #210) [INTERNALS] Added a Dockerfile for use when working on ack development. Thanks, M. Scott Ford. (GH #208) v3.0.0 Mon May 27 21:46:34 CDT 2019 ======================================== First official release of ack verison 3. See "Release notes for ack 3.0.0" at the bottom of this document for details of what has changed between ack 2.x and ack 3. [FIXES] Fixed a failing test if Pod::Perldoc::ToTextOverstrike was being used. (GH#202) 2.999_08 Sun May 19 20:33:13 CDT 2019 ===================================== [ENHANCEMENTS] Consolidated the manual and FAQ into one document, accessible with --man. Cookbook.pm has been moved to dev for future use. Added SVG filetype. [FIXES] Invalid options used to cause an error message triplicate. Fixes GH #192. 2.999_07 Sun Mar 31 21:54:55 CDT 2019 ===================================== [ENHANCEMENTS] Added --help-colors and --help-rgb-colors options to display colors available for color options. Many more mutex options have been added to help users know when they've made a mistake. For example, it doesn't make sense to have -C to show context when using -f to get a file list. Overhauled the handling of mutually exclusive options. We now properly handle mutex options even if they are abbreviated. The actual argument used is now shown. Fixes GH #57. 2.999_06 Thu Jan 10 20:37:23 CST 2019 ===================================== [ENHANCEMENTS] The --tt option for Template Toolkit is now --ttml. The short version still works. The standalone version of ack no longer supports the --faq or --cookbook options, which never worked right for it anyway. Instead, --man includes the FAQ and Cookbook. The --man option no longer uses the `perldoc` program for rendering the documentation. This means you'll have to pipe it into your own pager if you want scrolling, but it makes it much more portable. [FIXES] ack would stop finding files if there was a file named "0" in the current directory. Thanks, Rob Hoelz. (GH #162) [REMOVED FUNCTIONALITY] The --lines option has been removed. (GH #167) The -u short alias for --underline has been removed. (GH #173) 2.999_05 Sun Oct 21 21:37:39 CDT 2018 ===================================== [ENHANCEMENTS] Add -p as a shorter version of --proximate. 2.999_04 Thu Sep 6 17:45:07 CDT 2018 ===================================== [ENHANCEMENTS] Added -P as a negation of --proximate. It is the same as --proximate=0. If you have --proximate in an .ackrc, -P can be used to cancel it. Added --ts for Typescript. 2.999_03 Fri Jan 19 11:02:46 CST 2018 ===================================== [ENHANCEMENTS] The check for whether we need to scan the entire file line-by-line now reads 10M of file instead of just 100K. Removed support for the ACK_OPTIONS environment variable. Use an ackrc file instead. If you have ACK_OPTIONS set, ack will give a warning. Lots of internal speedups. 2.999_02 Mon Jan 8 23:03:42 CST 2018 ===================================== [ENHANCEMENTS] Added an optimization to make ack only do a line-by-line search of a file if there's a match somewhere in the file. This gives ack a 20-30% in timings of common cases. 2.999_01 Mon Jan 1 22:11:17 CST 2018 ===================================== [ENHANCEMENTS] Added --pod as a filetype, recognizing .pod as its extension. This is Perl's POD (Plain Old Documentation) format. Added --markdown as a filetype, recognizing .md and .markdown as extensions. --pager is no longer allowed in a project .ackrc file. --match and --output are not allowed in any .ackrc file. ack 3's new features are listed below for now. [FIXES] --lines had some mutex options that were not getting checked. Now, --lines is mutex with --passthru, --match and all context options. ============================= # Release notes for ack 3.0.0 ============================= # New features ack 3 is a greplike tool optimized for searching large code trees. Improvements over ack 2 include: * Improved `-w` option. * `-w` option will warn if your pattern does not lend itself to word matching. * `-i`, `-I` and `--smart-case` * `--proximate=N` option * Added `--pod` and `--markdown`. * Added `GNUmakefile` to the list of makefile specs. * Added `-S` as a synonym for `--smart-case`. # Bug fixes * Column numbers were not getting colorized in the output. Added `--color-colno` option and `ACK_COLOR_COLNO` environment variable. * A pattern that wanted whitespace at the end could match the linefeed at the end of a line. This is no longer possible. # Incompatibilities with ack 2 ## ack 3 requires Perl 5.10.1 ack 2 only needed Perl 5.8.8. This shouldn't be a problem since 5.10.1 has been out since 2009. ## ack 3 no longer highlights capture groups. ack 2 would highlight your capture groups. For example, ack '(set|get)_foo_(name|id)' would highlight the `set` or `get`, and the `name` or `id`, but not the full `set_user_id` that was matched. This feature was too confusing and has been removed. Now, the entire matching string is highlighted. ## ack 3's --output allows fewer special variables In ack 2, you could put any kind of Perl code in the `--output` option and it would get `eval`uated at run time, which would let you do tricky stuff like this gem from Mark Fowler (http://www.perladvent.org/2014/2014-12-21.html): ack --output='$&: @{[ eval "use LWP::Simple; 1" && length LWP::Simple::get($&) ]} bytes' \ 'https?://\S+' list.txt http://google.com/: 19529 bytes http://metacpan.org/: 7560 bytes http://www.perladvent.org/: 5562 bytes This has been a security problem in the past, and so in ack 3 we no longer `eval` the contents of `--output`. You're now restricted to the following variables: `$1` thru `$9`, `$_`, `$.`, `$&`, ``$` ``, `$'` and `$+`. You can also embed `\t`, `\n` and `\r` , and `$f` as stand-in for `$filename` in `ack2 --output` . �����������������������������������������������ack-v3.5.0/lib/�������������������������������������������������������������������������������������0000755�0001751�0001751�00000000000�14023040526�011657� 5����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/���������������������������������������������������������������������������������0000755�0001751�0001751�00000000000�14023040526�012377� 5����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/�����������������������������������������������������������������������������0000755�0001751�0001751�00000000000�14023040526�013075� 5����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/����������������������������������������������������������������������0000755�0001751�0001751�00000000000�14023040526�014322� 5����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/ExtensionGroup.pm�����������������������������������������������������0000644�0001751�0001751�00000001612�14023027176�017657� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::ExtensionGroup; =head1 NAME App::Ack::Filter::ExtensionGroup =head1 DESCRIPTION The App::Ack::Filter::ExtensionGroup class optimizes multiple ::Extension calls into one container. See App::Ack::Filter::IsGroup for details. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless { data => {}, }, $class; } sub add { my ( $self, $filter ) = @_; foreach my $ext (@{$filter->{extensions}}) { $self->{data}->{lc $ext} = 1; } return; } sub filter { my ( $self, $file ) = @_; if ($file->name =~ /[.]([^.]*)$/) { return exists $self->{'data'}->{lc $1}; } return 0; } sub inspect { my ( $self ) = @_; return ref($self) . " - $self"; } sub to_string { my ( $self ) = @_; return join(' ', map { ".$_" } sort keys %{$self->{data}}); } 1; ����������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Default.pm������������������������������������������������������������0000644�0001751�0001751�00000000645�14023027176�016257� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Default; =head1 NAME App::Ack::Filter::Default =head1 DESCRIPTION The class that implements the filter that ack uses by default if you don't specify any filters on the command line. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless {}, $class; } sub filter { my ( undef, $file ) = @_; return -T $file->name; } 1; �������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/IsPathGroup.pm��������������������������������������������������������0000644�0001751�0001751�00000001401�14023027176�017067� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::IsPathGroup; =head1 NAME App::Ack::Filter::IsPathGroup =head1 DESCRIPTION The App::Ack::Filter::IsPathGroup class optimizes multiple ::IsPath calls into one container. See App::Ack::Filter::IsGroup for details. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless { data => {}, }, $class; } sub add { my ( $self, $filter ) = @_; $self->{data}->{ $filter->{filename} } = 1; return; } sub filter { my ( $self, $file ) = @_; return exists $self->{data}->{$file->name}; } sub inspect { my ( $self ) = @_; return ref($self) . " - $self"; } sub to_string { my ( $self ) = @_; return join(' ', keys %{$self->{data}}); } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Is.pm�����������������������������������������������������������������0000644�0001751�0001751�00000001463�14023027176�015245� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Is; =head1 NAME App::Ack::Filter::Is =head1 DESCRIPTION Filters based on exact filename match. =cut use strict; use warnings; use parent 'App::Ack::Filter'; use File::Spec 3.00 (); use App::Ack::Filter::IsGroup (); sub new { my ( $class, $filename ) = @_; return bless { filename => $filename, groupname => 'IsGroup', }, $class; } sub create_group { return App::Ack::Filter::IsGroup->new(); } sub filter { my ( $self, $file ) = @_; return (File::Spec->splitpath($file->name))[2] eq $self->{filename}; } sub inspect { my ( $self ) = @_; return ref($self) . ' - ' . $self->{filename}; } sub to_string { my ( $self ) = @_; return $self->{filename}; } BEGIN { App::Ack::Filter->register_filter(is => __PACKAGE__); } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Match.pm��������������������������������������������������������������0000644�0001751�0001751�00000001551�14023027176�015724� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Match; use strict; use warnings; use parent 'App::Ack::Filter'; use App::Ack::Filter::MatchGroup (); =head1 NAME App::Ack::Filter::Match =head1 DESCRIPTION Implements filtering files by their filename (regular expression). =cut sub new { my ( $class, $re ) = @_; $re =~ s{^/|/$}{}g; # XXX validate? $re = qr/$re/i; return bless { regex => $re, groupname => 'MatchGroup', }, $class; } sub create_group { return App::Ack::Filter::MatchGroup->new; } sub filter { my ( $self, $file ) = @_; return $file->basename =~ /$self->{regex}/; } sub inspect { my ( $self ) = @_; return ref($self) . ' - ' . $self->{regex}; } sub to_string { my ( $self ) = @_; return "Filename matches $self->{regex}"; } BEGIN { App::Ack::Filter->register_filter(match => __PACKAGE__); } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Extension.pm����������������������������������������������������������0000644�0001751�0001751�00000001727�14023027176�016651� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Extension; =head1 NAME App::Ack::Filter::Extension =head1 DESCRIPTION Implements filters based on extensions. =cut use strict; use warnings; use parent 'App::Ack::Filter'; use App::Ack::Filter (); use App::Ack::Filter::ExtensionGroup (); sub new { my ( $class, @extensions ) = @_; my $exts = join('|', map { "\Q$_\E"} @extensions); my $re = qr/[.](?:$exts)$/i; return bless { extensions => \@extensions, regex => $re, groupname => 'ExtensionGroup', }, $class; } sub create_group { return App::Ack::Filter::ExtensionGroup->new(); } sub filter { my ( $self, $file ) = @_; return $file->name =~ /$self->{regex}/; } sub inspect { my ( $self ) = @_; return ref($self) . ' - ' . $self->{regex}; } sub to_string { my ( $self ) = @_; return join( ' ', map { ".$_" } @{$self->{extensions}} ); } BEGIN { App::Ack::Filter->register_filter(ext => __PACKAGE__); } 1; �����������������������������������������ack-v3.5.0/lib/App/Ack/Filter/FirstLineMatch.pm�����������������������������������������������������0000644�0001751�0001751�00000002002�14023027176�017534� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::FirstLineMatch; =head1 NAME App::Ack::Filter::FirstLineMatch =head1 DESCRIPTION The class that implements filtering files by their first line. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class, $re ) = @_; $re =~ s{^/|/$}{}g; # XXX validate? $re = qr{$re}i; return bless { regex => $re, }, $class; } # This test reads the first 250 characters of a file, then just uses the # first line found in that. This prevents reading something like an entire # .min.js file (which might be only one "line" long) into memory. sub filter { my ( $self, $file ) = @_; return $file->firstliney =~ /$self->{regex}/; } sub inspect { my ( $self ) = @_; return ref($self) . ' - ' . $self->{regex}; } sub to_string { my ( $self ) = @_; (my $re = $self->{regex}) =~ s{\([^:]*:(.*)\)$}{$1}; return "First line matches /$re/"; } BEGIN { App::Ack::Filter->register_filter(firstlinematch => __PACKAGE__); } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/MatchGroup.pm���������������������������������������������������������0000644�0001751�0001751�00000001531�14023027176�016737� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::MatchGroup; =head1 NAME App::Ack::Filter::MatchGroup =head1 DESCRIPTION The App::Ack::Filter::MatchGroup class optimizes multiple ::Match calls into one container. See App::Ack::Filter::IsGroup for details. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless { matches => [], big_re => undef, }, $class; } sub add { my ( $self, $filter ) = @_; push @{ $self->{matches} }, $filter->{regex}; my $re = join('|', map { "(?:$_)" } @{ $self->{matches} }); $self->{big_re} = qr/$re/; return; } sub filter { my ( $self, $file ) = @_; return $file->basename =~ /$self->{big_re}/; } # This class has no inspect() or to_string() method. # It will just use the default one unless someone writes something useful. 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/IsPath.pm�������������������������������������������������������������0000644�0001751�0001751�00000001276�14023027176�016064� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::IsPath; =head1 NAME App::Ack::Filter::IsPath =head1 DESCRIPTION Filters based on path. =cut use strict; use warnings; use parent 'App::Ack::Filter'; use App::Ack::Filter::IsPathGroup (); sub new { my ( $class, $filename ) = @_; return bless { filename => $filename, groupname => 'IsPathGroup', }, $class; } sub create_group { return App::Ack::Filter::IsPathGroup->new(); } sub filter { my ( $self, $file ) = @_; return $file->name eq $self->{filename}; } sub inspect { my ( $self ) = @_; return ref($self) . ' - ' . $self->{filename}; } sub to_string { my ( $self ) = @_; return $self->{filename}; } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Collection.pm���������������������������������������������������������0000644�0001751�0001751�00000002476�14023027176�016772� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Collection; =head1 NAME App::Ack::Filter::Collection =head1 DESCRIPTION The Ack::Filter::Collection class can contain filters and internally sort them into groups. The groups can then be optimized for faster filtering. Filters are grouped and replaced by a fast hash lookup. This leads to improved performance when many such filters are active, like when using the C<--known> command line option. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless { groups => {}, ungrouped => [], }, $class; } sub filter { my ( $self, $file ) = @_; for my $group (values %{$self->{groups}}) { return 1 if $group->filter($file); } for my $filter (@{$self->{ungrouped}}) { return 1 if $filter->filter($file); } return 0; } sub add { my ( $self, $filter ) = @_; if (exists $filter->{'groupname'}) { my $group = ($self->{groups}->{$filter->{groupname}} ||= $filter->create_group()); $group->add($filter); } else { push @{$self->{'ungrouped'}}, $filter; } return; } sub inspect { my ( $self ) = @_; return ref($self) . " - $self"; } sub to_string { my ( $self ) = @_; return join(', ', map { "($_)" } @{$self->{ungrouped}}); } 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/Inverse.pm������������������������������������������������������������0000644�0001751�0001751�00000001151�14023027176�016277� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::Inverse; =head1 NAME App::Ack::Filter::Inverse =head1 DESCRIPTION The filter class that inverts another filter. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class, $filter ) = @_; return bless { filter => $filter, }, $class; } sub filter { my ( $self, $file ) = @_; return !$self->{filter}->filter( $file ); } sub invert { my $self = shift; return $self->{'filter'}; } sub is_inverted { return 1; } sub inspect { my ( $self ) = @_; my $filter = $self->{'filter'}; return "!$filter"; } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter/IsGroup.pm������������������������������������������������������������0000644�0001751�0001751�00000002073�14023027176�016260� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter::IsGroup; =head1 NAME App::Ack::Filter::IsGroup =head1 DESCRIPTION The App::Ack::Filter::IsGroup class optimizes multiple App::Ack::Filter::Is calls into one container. Let's say you have 100 C<--type-add=is:...> filters. You could have my @filters = map { make_is_filter($_) } 1..100; and then do if ( any { $_->filter($rsrc) } @filters ) { ... } but that's slow, because of of method lookup overhead, function call overhead, etc. So ::Is filters know how to organize themselves into an ::IsGroup filter. =cut use strict; use warnings; use parent 'App::Ack::Filter'; sub new { my ( $class ) = @_; return bless { data => {}, }, $class; } sub add { my ( $self, $filter ) = @_; $self->{data}->{ $filter->{filename} } = 1; return; } sub filter { my ( $self, $file ) = @_; return exists $self->{data}->{ $file->basename }; } sub inspect { my ( $self ) = @_; return ref($self) . " - $self"; } sub to_string { my ( $self ) = @_; return join(' ', keys %{$self->{data}}); } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/File.pm����������������������������������������������������������������������0000644�0001751�0001751�00000011054�14023027176�014321� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::File; use warnings; use strict; use App::Ack (); use File::Spec (); =head1 NAME App::Ack::File =head1 DESCRIPTION Abstracts a file from the filesystem. =head1 METHODS =head2 new( $filename ) Opens the file specified by I<$filename> and returns a filehandle and a flag that says whether it could be binary. If there's a failure, it throws a warning and returns an empty list. =cut sub new { my $class = shift; my $filename = shift; my $self = bless { filename => $filename, fh => undef, }, $class; if ( $self->{filename} eq '-' ) { $self->{fh} = *STDIN; } return $self; } =head2 $file->name() Returns the name of the file. =cut sub name { return $_[0]->{filename}; } =head2 $file->basename() Returns the basename (the last component the path) of the file. =cut sub basename { my ( $self ) = @_; return $self->{basename} //= (File::Spec->splitpath($self->name))[2]; } =head2 $file->open() Opens a filehandle for reading this file and returns it, or returns undef if the operation fails (the error is in C<$!>). Instead of calling C<close $fh>, C<$file-E<gt>close> should be called. =cut sub open { my ( $self ) = @_; if ( !$self->{fh} ) { if ( open $self->{fh}, '<', $self->{filename} ) { # Do nothing. } else { $self->{fh} = undef; } } return $self->{fh}; } sub may_be_present { my $self = shift; my $regex = shift; # Tells if the file needs a line-by-line scan. This is a big # optimization because if you can tell from the outset that the pattern # is not found in the file at all, then there's no need to do the # line-by-line iteration. # Slurp up an entire file up to 10M, see if there are any matches # in it, and if so, let us know so we can iterate over it directly. # The $regex may be undef if it had a "$" in it, and is therefore unsuitable for this heuristic. my $may_be_present = 1; if ( $regex && $self->open() && -f $self->{fh} ) { my $buffer; my $size = 10_000_000; my $rc = sysread( $self->{fh}, $buffer, $size ); if ( !defined($rc) ) { if ( $App::Ack::report_bad_filenames ) { App::Ack::warn( $self->name . ": $!" ); } $may_be_present = 0; } else { # If we read all 10M, then we need to scan the rest. # If there are any carriage returns, our results are flaky, so scan the rest. if ( ($rc == $size) || (index($buffer,"\r") >= 0) ) { $may_be_present = 1; } else { if ( $buffer !~ /$regex/o ) { $may_be_present = 0; } } } } return $may_be_present; } =head2 $file->reset() Resets the file back to the beginning. This is only called if C<may_be_present()> is true, but not always if C<may_be_present()> is true. =cut sub reset { my $self = shift; if ( defined($self->{fh}) ) { return unless -f $self->{fh}; if ( !seek( $self->{fh}, 0, 0 ) && $App::Ack::report_bad_filenames ) { App::Ack::warn( "$self->{filename}: $!" ); } } return; } =head2 $file->close() Close the file. =cut sub close { my $self = shift; if ( $self->{fh} ) { if ( !close($self->{fh}) && $App::Ack::report_bad_filenames ) { App::Ack::warn( $self->name() . ": $!" ); } $self->{fh} = undef; } return; } =head2 $file->clone() Clones this file. =cut sub clone { my ( $self ) = @_; return __PACKAGE__->new($self->name); } =head2 $file->firstliney() Returns the first line of a file (or first 250 characters, whichever comes first). =cut sub firstliney { my ( $self ) = @_; if ( !exists $self->{firstliney} ) { my $fh = $self->open(); if ( !$fh ) { if ( $App::Ack::report_bad_filenames ) { App::Ack::warn( $self->name . ': ' . $! ); } $self->{firstliney} = ''; } else { my $buffer; my $rc = sysread( $fh, $buffer, 250 ); if ( $rc ) { $buffer =~ s/[\r\n].*//s; } else { if ( !defined($rc) ) { App::Ack::warn( $self->name . ': ' . $! ); } $buffer = ''; } $self->{firstliney} = $buffer; $self->reset; } } return $self->{firstliney}; } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/ConfigDefault.pm�������������������������������������������������������������0000644�0001751�0001751�00000023726�14023040515�016155� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::ConfigDefault; use warnings; use strict; use App::Ack (); =head1 NAME App::Ack::ConfigDefault =head1 DESCRIPTION A module that contains the default configuration for ack. =cut sub options { return split( /\n/, _options_block() ); } sub options_clean { return grep { /./ && !/^#/ } options(); } sub _options_block { my $lines = <<'HERE'; # This is the default ackrc for ack version ==VERSION==. # There are four different ways to match # # is: Match the filename exactly # # ext: Match the extension of the filename exactly # # match: Match the filename against a Perl regular expression # # firstlinematch: Match the first 250 characters of the first line # of text against a Perl regular expression. This is only for # the --type-add option. ### Directories to ignore # Bazaar # https://bazaar.canonical.com/ --ignore-directory=is:.bzr # Codeville # http://freshmeat.sourceforge.net/projects/codeville --ignore-directory=is:.cdv # Interface Builder (Xcode) # https://en.wikipedia.org/wiki/Interface_Builder --ignore-directory=is:~.dep --ignore-directory=is:~.dot --ignore-directory=is:~.nib --ignore-directory=is:~.plst # Git # https://git-scm.com/ --ignore-directory=is:.git # When submodules are used, .git is a file. --ignore-file=is:.git # Mercurial # https://www.mercurial-scm.org/ --ignore-directory=is:.hg # Quilt # https://directory.fsf.org/wiki/Quilt --ignore-directory=is:.pc # Subversion # https://subversion.apache.org/ --ignore-directory=is:.svn # Monotone # https://www.monotone.ca/ --ignore-directory=is:_MTN # CVS # https://savannah.nongnu.org/projects/cvs --ignore-directory=is:CVS # RCS # https://www.gnu.org/software/rcs/ --ignore-directory=is:RCS # SCCS # https://en.wikipedia.org/wiki/Source_Code_Control_System --ignore-directory=is:SCCS # darcs # http://darcs.net/ --ignore-directory=is:_darcs # Vault/Fortress --ignore-directory=is:_sgbak # autoconf # https://www.gnu.org/software/autoconf/ --ignore-directory=is:autom4te.cache # Perl module building --ignore-directory=is:blib --ignore-directory=is:_build # Perl Devel::Cover module's output directory # https://metacpan.org/release/Devel-Cover --ignore-directory=is:cover_db # Node modules created by npm --ignore-directory=is:node_modules # CMake cache # https://www.cmake.org/ --ignore-directory=is:CMakeFiles # Eclipse workspace folder # https://eclipse.org/ --ignore-directory=is:.metadata # Cabal (Haskell) sandboxes # https://www.haskell.org/cabal/users-guide/installing-packages.html --ignore-directory=is:.cabal-sandbox # Python caches # https://docs.python.org/3/tutorial/modules.html --ignore-directory=is:__pycache__ --ignore-directory=is:.pytest_cache # macOS Finder remnants --ignore-directory=is:__MACOSX --ignore-file=is:.DS_Store ### Files to ignore # Backup files --ignore-file=ext:bak --ignore-file=match:/~$/ # Emacs swap files --ignore-file=match:/^#.+#$/ # vi/vim swap files https://www.vim.org/ --ignore-file=match:/[._].*[.]swp$/ # core dumps --ignore-file=match:/core[.]\d+$/ # minified Javascript --ignore-file=match:/[.-]min[.]js$/ --ignore-file=match:/[.]js[.]min$/ # minified CSS --ignore-file=match:/[.]min[.]css$/ --ignore-file=match:/[.]css[.]min$/ # JS and CSS source maps --ignore-file=match:/[.]js[.]map$/ --ignore-file=match:/[.]css[.]map$/ # PDFs, because they pass Perl's -T detection --ignore-file=ext:pdf # Common graphics, just as an optimization --ignore-file=ext:gif,jpg,jpeg,png # Common archives, as an optimization --ignore-file=ext:gz,tar,tgz,zip # Python compiles modules --ignore-file=ext:pyc,pyd,pyo # C extensions --ignore-file=ext:so # Compiled gettext files --ignore-file=ext:mo ### Filetypes defined # Makefiles # https://www.gnu.org/s/make/ --type-add=make:ext:mk --type-add=make:ext:mak --type-add=make:is:makefile --type-add=make:is:Makefile --type-add=make:is:Makefile.Debug --type-add=make:is:Makefile.Release --type-add=make:is:GNUmakefile # Rakefiles # https://rake.rubyforge.org/ --type-add=rake:is:Rakefile # CMake # https://cmake.org/ --type-add=cmake:is:CMakeLists.txt --type-add=cmake:ext:cmake # Bazel build tool # https://docs.bazel.build/versions/master/skylark/bzl-style.html --type-add=bazel:ext:bzl # https://docs.bazel.build/versions/master/guide.html#bazelrc-the-bazel-configuration-file --type-add=bazel:ext:bazelrc # https://docs.bazel.build/versions/master/build-ref.html#BUILD_files --type-add=bazel:is:BUILD # https://docs.bazel.build/versions/master/build-ref.html#workspace --type-add=bazel:is:WORKSPACE # Actionscript --type-add=actionscript:ext:as,mxml # Ada # https://www.adaic.org/ --type-add=ada:ext:ada,adb,ads # ASP # https://docs.microsoft.com/en-us/previous-versions/office/developer/server-technologies/aa286483(v=msdn.10) --type-add=asp:ext:asp # ASP.Net # https://dotnet.microsoft.com/apps/aspnet --type-add=aspx:ext:master,ascx,asmx,aspx,svc # Assembly --type-add=asm:ext:asm,s # DOS/Windows batch --type-add=batch:ext:bat,cmd # ColdFusion # https://en.wikipedia.org/wiki/ColdFusion --type-add=cfmx:ext:cfc,cfm,cfml # Clojure # https://clojure.org/ --type-add=clojure:ext:clj,cljs,edn,cljc # C # .xs are Perl C files --type-add=cc:ext:c,h,xs # C header files --type-add=hh:ext:h # CoffeeScript # https://coffeescript.org/ --type-add=coffeescript:ext:coffee # C++ --type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx # C++ header files --type-add=hpp:ext:hpp,hh,h,hxx # C# --type-add=csharp:ext:cs # CSS # https://www.w3.org/Style/CSS/ --type-add=css:ext:css # Dart # https://dart.dev/ --type-add=dart:ext:dart # Delphi # https://en.wikipedia.org/wiki/Embarcadero_Delphi --type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj # Elixir # https://elixir-lang.org/ --type-add=elixir:ext:ex,exs # Elm # https://elm-lang.org --type-add=elm:ext:elm # Emacs Lisp # https://www.gnu.org/software/emacs --type-add=elisp:ext:el # Erlang # https://www.erlang.org/ --type-add=erlang:ext:erl,hrl # Fortran # https://en.wikipedia.org/wiki/Fortran --type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp # Go # https://golang.org/ --type-add=go:ext:go # Groovy # https://www.groovy-lang.org/ --type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle # GSP # https://gsp.grails.org/ --type-add=gsp:ext:gsp # Haskell # https://www.haskell.org/ --type-add=haskell:ext:hs,lhs # HTML --type-add=html:ext:htm,html,xhtml # Jade # http://jade-lang.com/ --type-add=jade:ext:jade # Java # https://www.oracle.com/technetwork/java/index.html --type-add=java:ext:java,properties # JavaScript --type-add=js:ext:js # JSP # https://www.oracle.com/technetwork/java/javaee/jsp/index.html --type-add=jsp:ext:jsp,jspx,jspf,jhtm,jhtml # JSON # https://json.org/ --type-add=json:ext:json # Kotlin # https://kotlinlang.org/ --type-add=kotlin:ext:kt,kts # Less # http://www.lesscss.org/ --type-add=less:ext:less # Common Lisp # https://common-lisp.net/ --type-add=lisp:ext:lisp,lsp # Lua # https://www.lua.org/ --type-add=lua:ext:lua --type-add=lua:firstlinematch:/^#!.*\blua(jit)?/ # Markdown # https://en.wikipedia.org/wiki/Markdown --type-add=markdown:ext:md,markdown # We understand that there are many ad hoc extensions for markdown # that people use. .md and .markdown are the two that ack recognizes. # You are free to add your own in your ackrc file. # Matlab # https://en.wikipedia.org/wiki/MATLAB --type-add=matlab:ext:m # Objective-C --type-add=objc:ext:m,h # Objective-C++ --type-add=objcpp:ext:mm,h # OCaml # https://ocaml.org/ --type-add=ocaml:ext:ml,mli,mll,mly # Perl # https://perl.org/ --type-add=perl:ext:pl,pm,pod,t,psgi --type-add=perl:firstlinematch:/^#!.*\bperl/ # Perl tests --type-add=perltest:ext:t # Perl's Plain Old Documentation format, POD --type-add=pod:ext:pod # PHP # https://www.php.net/ --type-add=php:ext:php,phpt,php3,php4,php5,phtml --type-add=php:firstlinematch:/^#!.*\bphp/ # Plone # https://plone.org/ --type-add=plone:ext:pt,cpt,metadata,cpy,py # PureScript # https://www.purescript.org --type-add=purescript:ext:purs # Python # https://www.python.org/ --type-add=python:ext:py --type-add=python:firstlinematch:/^#!.*\bpython/ # R # https://www.r-project.org/ --type-add=rr:ext:R # reStructured Text # https://docutils.sourceforge.io/rst.html --type-add=rst:ext:rst # Ruby # https://www.ruby-lang.org/ --type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec --type-add=ruby:is:Rakefile --type-add=ruby:firstlinematch:/^#!.*\bruby/ # Rust # https://www.rust-lang.org/ --type-add=rust:ext:rs # Sass # https://sass-lang.com --type-add=sass:ext:sass,scss # Scala # https://www.scala-lang.org/ --type-add=scala:ext:scala # Scheme # https://groups.csail.mit.edu/mac/projects/scheme/ --type-add=scheme:ext:scm,ss # Shell --type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish --type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/ # Smalltalk # http://www.smalltalk.org/ --type-add=smalltalk:ext:st # Smarty # https://www.smarty.net/ --type-add=smarty:ext:tpl # SQL # https://www.iso.org/standard/45498.html --type-add=sql:ext:sql,ctl # Stylus # http://stylus-lang.com/ --type-add=stylus:ext:styl # SVG # https://en.wikipedia.org/wiki/Scalable_Vector_Graphics --type-add=svg:ext:svg # Swift # https://developer.apple.com/swift/ --type-add=swift:ext:swift --type-add=swift:firstlinematch:/^#!.*\bswift/ # Tcl # https://www.tcl.tk/ --type-add=tcl:ext:tcl,itcl,itk # TeX & LaTeX # https://www.latex-project.org/ --type-add=tex:ext:tex,cls,sty # Template Toolkit (Perl) # http//template-toolkit.org/ --type-add=ttml:ext:tt,tt2,ttml # TOML # https://toml.io/ --type-add=toml:ext:toml # Typescript # https://www.typescriptlang.org/ --type-add=ts:ext:ts,tsx # Visual Basic --type-add=vb:ext:bas,cls,frm,ctl,vb,resx # Verilog --type-add=verilog:ext:v,vh,sv # VHDL # http://www.eda.org/twiki/bin/view.cgi/P1076/WebHome --type-add=vhdl:ext:vhd,vhdl # Vim # https://www.vim.org/ --type-add=vim:ext:vim # XML # https://www.w3.org/TR/REC-xml/ --type-add=xml:ext:xml,dtd,xsd,xsl,xslt,ent,wsdl --type-add=xml:firstlinematch:/<[?]xml/ # YAML # https://yaml.org/ --type-add=yaml:ext:yaml,yml HERE $lines =~ s/==VERSION==/$App::Ack::VERSION/sm; return $lines; } 1; ������������������������������������������ack-v3.5.0/lib/App/Ack/Files.pm���������������������������������������������������������������������0000644�0001751�0001751�00000004532�14023027176�014507� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Files; use App::Ack (); use App::Ack::File (); use File::Next 1.16 (); use warnings; use strict; use 5.010; =head1 NAME App::Ack::Files =head1 SYNOPSIS A factory object for creating a stream of L<App::Ack::File> objects. =head1 METHODS =head2 from_argv( \%opt, \@starting_points ) Return an iterator that does the file finding for us. =cut sub from_argv { my $class = shift; my $opt = shift; my $start = shift; my $self = bless {}, $class; my $descend_filter = $opt->{descend_filter}; if ( $opt->{n} ) { $descend_filter = sub { return 0; }; } $self->{iter} = File::Next::files( { file_filter => $opt->{file_filter}, descend_filter => $descend_filter, error_handler => _generate_error_handler(), warning_handler => sub {}, sort_files => $opt->{sort_files}, follow_symlinks => $opt->{follow}, }, @{$start} ); return $self; } =head2 from_file( \%opt, $filename ) Return an iterator that reads the list of files to search from a given file. If I<$filename> is '-', then it reads from STDIN. =cut sub from_file { my $class = shift; my $opt = shift; my $file = shift; my $error_handler = _generate_error_handler(); my $iter = File::Next::from_file( { error_handler => $error_handler, warning_handler => $error_handler, sort_files => $opt->{sort_files}, }, $file ) or return undef; return bless { iter => $iter, }, $class; } =head2 from_stdin() This is for reading input lines from STDIN, not the list of files from STDIN. =cut sub from_stdin { my $class = shift; my $self = bless {}, $class; $self->{iter} = sub { state $has_been_called = 0; if ( !$has_been_called ) { $has_been_called = 1; return '-'; } return; }; return $self; } sub next { my $self = shift; my $file = $self->{iter}->(); return unless defined($file); return App::Ack::File->new( $file ); } sub _generate_error_handler { if ( $App::Ack::report_bad_filenames ) { return sub { my $msg = shift; App::Ack::warn( $msg ); }; } else { return sub {}; } } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/ConfigFinder.pm��������������������������������������������������������������0000644�0001751�0001751�00000006660�14023027176�016006� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::ConfigFinder; =head1 NAME App::Ack::ConfigFinder =head1 DESCRIPTION A module that contains the logic for locating the various configuration files. =head1 LOCATING CONFIG FILES First, ack looks for a global ackrc. =over =item On Windows, this is `ackrc` in either COMMON_APPDATA or APPDATA. If `ackrc` is present in both directories, ack uses both files in that order. =item On a non-Windows OS, this is `/etc/ackrc`. =back Then, ack looks for a user-specific ackrc if the HOME environment variable is set. This is either F<$HOME/.ackrc> or F<$HOME/_ackrc>. Then, ack looks for a project-specific ackrc file. ack searches up the directory hierarchy for the first `.ackrc` or `_ackrc` file. If this is one of the ackrc files found in the previous steps, it is not loaded again. It is a fatal error if a directory contains both F<.ackrc> and F<_ackrc>. After ack loads the options from the found ackrc files, ack looks at the C<ACKRC_OPTIONS> environment variable. Finally, ack takes settings from the command line. =cut use strict; use warnings; use App::Ack (); use Cwd 3.00 (); use File::Spec 3.00 (); use if ($^O eq 'MSWin32'), 'Win32'; =head1 METHODS =head2 new Creates a new config finder. =cut sub new { my ( $class ) = @_; return bless {}, $class; } sub _remove_redundancies { my @configs = @_; my %seen; my @uniq; foreach my $config (@configs) { my $path = $config->{path}; my $key = -e $path ? Cwd::realpath( $path ) : $path; if ( not $App::Ack::is_windows ) { # On Unix, uniquify on inode. my ($dev, $inode) = (stat $key)[0, 1]; $key = "$dev:$inode" if defined $dev; } push( @uniq, $config ) unless $seen{$key}++; } return @uniq; } sub _check_for_ackrc { return unless defined $_[0]; my @files = grep { -f } map { File::Spec->catfile(@_, $_) } qw(.ackrc _ackrc); App::Ack::die( File::Spec->catdir(@_) . ' contains both .ackrc and _ackrc. Please remove one of those files.' ) if @files > 1; return wantarray ? @files : $files[0]; } # end _check_for_ackrc =head2 $finder->find_config_files Locates config files, and returns a list of them. =cut sub find_config_files { my @config_files; if ( $App::Ack::is_windows ) { push @config_files, map { +{ path => File::Spec->catfile($_, 'ackrc') } } ( Win32::GetFolderPath(Win32::CSIDL_COMMON_APPDATA()), Win32::GetFolderPath(Win32::CSIDL_APPDATA()), ); } else { push @config_files, { path => '/etc/ackrc' }; } if ( $ENV{'ACKRC'} && -f $ENV{'ACKRC'} ) { push @config_files, { path => $ENV{'ACKRC'} }; } else { push @config_files, map { +{ path => $_ } } _check_for_ackrc($ENV{'HOME'}); } my $cwd = Cwd::getcwd(); return () unless defined $cwd; # XXX This should go through some untainted cwd-fetching function, and not get untainted brute-force like this. $cwd =~ /(.+)/; $cwd = $1; my @dirs = File::Spec->splitdir( $cwd ); while ( @dirs ) { my $ackrc = _check_for_ackrc(@dirs); if ( defined $ackrc ) { push @config_files, { project => 1, path => $ackrc }; last; } pop @dirs; } # We only test for existence here, so if the file is deleted out from under us, this will fail later. return _remove_redundancies( @config_files ); } 1; ��������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/ConfigLoader.pm��������������������������������������������������������������0000644�0001751�0001751�00000074150�14023040515�015774� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::ConfigLoader; use strict; use warnings; use 5.010; use App::Ack (); use App::Ack::ConfigDefault (); use App::Ack::ConfigFinder (); use App::Ack::Filter (); use App::Ack::Filter::Collection (); use App::Ack::Filter::Default (); use App::Ack::Filter::IsPath (); use File::Spec 3.00 (); use Getopt::Long 2.38 (); use Text::ParseWords 3.1 (); sub configure_parser { my @opts = @_; my @standard = qw( default bundling no_auto_help no_auto_version no_ignore_case ); Getopt::Long::Configure( @standard, @opts ); } sub _generate_ignore_dir { my ( $option_name, $opt ) = @_; my $is_inverted = $option_name =~ /^--no/; return sub { my ( undef, $dir ) = @_; $dir = _remove_directory_separator( $dir ); if ( $dir !~ /:/ ) { $dir = 'is:' . $dir; } my ( $filter_type, $args ) = split /:/, $dir, 2; if ( $filter_type eq 'firstlinematch' ) { App::Ack::die( qq{Invalid filter specification "$filter_type" for option '$option_name'} ); } my $filter = App::Ack::Filter->create_filter($filter_type, split(/,/, $args)); my $collection; my $previous_inversion_matches = $opt->{idirs} && !($is_inverted xor $opt->{idirs}[-1]->is_inverted()); if ( $previous_inversion_matches ) { $collection = $opt->{idirs}[-1]; if ( $is_inverted ) { # This relies on invert of an inverted filter to return the original. $collection = $collection->invert(); } } else { $collection = App::Ack::Filter::Collection->new(); push @{ $opt->{idirs} }, $is_inverted ? $collection->invert() : $collection; } $collection->add($filter); if ( $filter_type eq 'is' ) { $collection->add(App::Ack::Filter::IsPath->new($args)); } }; } sub _remove_directory_separator { my $path = shift; state $dir_sep_chars = $App::Ack::is_windows ? quotemeta( '\\/' ) : quotemeta( File::Spec->catfile( '', '' ) ); $path =~ s/[$dir_sep_chars]$//; return $path; } sub _process_filter_spec { my ( $spec ) = @_; if ( $spec =~ /^(\w+):(\w+):(.*)/ ) { my ( $type_name, $ext_type, $arguments ) = ( $1, $2, $3 ); return ( $type_name, App::Ack::Filter->create_filter($ext_type, split(/,/, $arguments)) ); } elsif ( $spec =~ /^(\w+)=(.*)/ ) { # Check to see if we have ack1-style argument specification. my ( $type_name, $extensions ) = ( $1, $2 ); my @extensions = split(/,/, $extensions); foreach my $extension ( @extensions ) { $extension =~ s/^[.]//; } return ( $type_name, App::Ack::Filter->create_filter('ext', @extensions) ); } else { App::Ack::die( "Invalid filter specification '$spec'" ); } } sub _uninvert_filter { my ( $opt, @filters ) = @_; return unless defined $opt->{filters} && @filters; # Loop through all the registered filters. If we hit one that # matches this extension and it's inverted, we need to delete it from # the options. for ( my $i = 0; $i < @{ $opt->{filters} }; $i++ ) { my $opt_filter = @{ $opt->{filters} }[$i]; # XXX Do a real list comparison? This just checks string equivalence. if ( $opt_filter->is_inverted() && "$opt_filter->{filter}" eq "@filters" ) { splice @{ $opt->{filters} }, $i, 1; $i--; } } return; } sub _process_filetypes { my ( $opt, $arg_sources ) = @_; my %additional_specs; my $add_spec = sub { my ( undef, $spec ) = @_; my ( $name, $filter ) = _process_filter_spec($spec); push @{ $App::Ack::mappings{$name} }, $filter; $additional_specs{$name . '!'} = sub { my ( undef, $value ) = @_; my @filters = @{ $App::Ack::mappings{$name} }; if ( not $value ) { @filters = map { $_->invert() } @filters; } else { _uninvert_filter( $opt, @filters ); } push @{ $opt->{'filters'} }, @filters; }; }; my $set_spec = sub { my ( undef, $spec ) = @_; my ( $name, $filter ) = _process_filter_spec($spec); $App::Ack::mappings{$name} = [ $filter ]; $additional_specs{$name . '!'} = sub { my ( undef, $value ) = @_; my @filters = @{ $App::Ack::mappings{$name} }; if ( not $value ) { @filters = map { $_->invert() } @filters; } push @{ $opt->{'filters'} }, @filters; }; }; my $delete_spec = sub { my ( undef, $name ) = @_; delete $App::Ack::mappings{$name}; delete $additional_specs{$name . '!'}; }; my %type_arg_specs = ( 'type-add=s' => $add_spec, 'type-set=s' => $set_spec, 'type-del=s' => $delete_spec, ); configure_parser( 'no_auto_abbrev', 'pass_through' ); foreach my $source (@{$arg_sources}) { my $args = $source->{contents}; if ( ref($args) ) { # $args are modified in place, so no need to munge $arg_sources Getopt::Long::GetOptionsFromArray( $args, %type_arg_specs ); } else { ( undef, $source->{contents} ) = Getopt::Long::GetOptionsFromString( $args, %type_arg_specs ); } } $additional_specs{'k|known-types'} = sub { my @filters = map { @{$_} } values(%App::Ack::mappings); push @{ $opt->{'filters'} }, @filters; }; return \%additional_specs; } sub get_arg_spec { my ( $opt, $extra_specs ) = @_; =begin Adding-Options *** IF YOU ARE MODIFYING ACK PLEASE READ THIS *** If you plan to add a new option to ack, please make sure of the following: * Your new option has a test underneath the t/ directory. * Your new option is explained when a user invokes ack --help. (See App::Ack::show_help) * Your new option is explained when a user invokes ack --man. (See the POD at the end of ./ack) * Add your option to t/config-loader.t * Add your option to t/Util.pm#get_expected_options * Add your option's description and aliases to dev/generate-completion-scripts.pl * Go through the list of options already available, and consider whether your new option can be considered mutex with another option. =end Adding-Options =cut sub _type_handler { my ( $getopt, $value ) = @_; my $cb_value = 1; if ( $value =~ s/^no// ) { $cb_value = 0; } my $callback; { no warnings; $callback = $extra_specs->{ $value . '!' }; } if ( $callback ) { $callback->( $getopt, $cb_value ); } else { App::Ack::die( "Unknown type '$value'" ); } return; } return { 1 => sub { $opt->{1} = $opt->{m} = 1 }, 'A|after-context:-1' => sub { shift; $opt->{A} = _context_value(shift) }, 'B|before-context:-1' => sub { shift; $opt->{B} = _context_value(shift) }, 'C|context:-1' => sub { shift; $opt->{B} = $opt->{A} = _context_value(shift) }, 'break!' => \$opt->{break}, 'c|count' => \$opt->{c}, 'color|colour!' => \$opt->{color}, 'color-match=s' => \$ENV{ACK_COLOR_MATCH}, 'color-filename=s' => \$ENV{ACK_COLOR_FILENAME}, 'color-colno=s' => \$ENV{ACK_COLOR_COLNO}, 'color-lineno=s' => \$ENV{ACK_COLOR_LINENO}, 'column!' => \$opt->{column}, 'create-ackrc' => sub { say for ( '--ignore-ack-defaults', App::Ack::ConfigDefault::options() ); exit; }, 'debug' => \$opt->{debug}, 'env!' => sub { my ( undef, $value ) = @_; if ( !$value ) { $opt->{noenv_seen} = 1; } }, f => \$opt->{f}, 'files-from=s' => \$opt->{files_from}, 'filter!' => \$App::Ack::is_filter_mode, flush => sub { $| = 1 }, 'follow!' => \$opt->{follow}, g => \$opt->{g}, 'group!' => sub { shift; $opt->{heading} = $opt->{break} = shift }, 'heading!' => \$opt->{heading}, 'h|no-filename' => \$opt->{h}, 'H|with-filename' => \$opt->{H}, 'i|ignore-case' => sub { $opt->{i} = 1; $opt->{S} = 0; }, 'I|no-ignore-case' => sub { $opt->{i} = 0; $opt->{S} = 0; }, 'ignore-directory|ignore-dir=s' => _generate_ignore_dir('--ignore-dir', $opt), 'ignore-file=s' => sub { my ( undef, $file ) = @_; my ( $filter_type, $args ) = split /:/, $file, 2; my $filter = App::Ack::Filter->create_filter($filter_type, split(/,/, $args//'')); if ( !$opt->{ifiles} ) { $opt->{ifiles} = App::Ack::Filter::Collection->new(); } $opt->{ifiles}->add($filter); }, 'l|files-with-matches' => \$opt->{l}, 'L|files-without-matches' => \$opt->{L}, 'm|max-count=i' => \$opt->{m}, 'match=s' => \$opt->{regex}, 'n|no-recurse' => \$opt->{n}, o => sub { $opt->{output} = '$&' }, 'output=s' => \$opt->{output}, 'pager:s' => sub { my ( undef, $value ) = @_; $opt->{pager} = $value || $ENV{PAGER}; }, 'noignore-directory|noignore-dir=s' => _generate_ignore_dir('--noignore-dir', $opt), 'nopager' => sub { $opt->{pager} = undef }, 'passthru' => \$opt->{passthru}, 'print0' => \$opt->{print0}, 'p|proximate:1' => \$opt->{p}, 'P' => sub { $opt->{p} = 0 }, 'Q|literal' => \$opt->{Q}, 'r|R|recurse' => sub { $opt->{n} = 0 }, 'range-start=s' => \$opt->{range_start}, 'range-end=s' => \$opt->{range_end}, 'range-invert!' => \$opt->{range_invert}, 's' => \$opt->{s}, 'show-types' => \$opt->{show_types}, 'S|smart-case!' => sub { my (undef,$value) = @_; $opt->{S} = $value; $opt->{i} = 0 if $value; }, 'sort-files' => \$opt->{sort_files}, 't|type=s' => \&_type_handler, 'T=s' => sub { my ($getopt,$value) = @_; $value="no$value"; _type_handler($getopt,$value); }, 'underline!' => \$opt->{underline}, 'v|invert-match' => \$opt->{v}, 'w|word-regexp' => \$opt->{w}, 'x' => sub { $opt->{files_from} = '-' }, 'help' => sub { App::Ack::show_help(); exit; }, 'help-types' => sub { App::Ack::show_help_types(); exit; }, 'help-colors' => sub { App::Ack::show_help_colors(); exit; }, 'help-rgb-colors' => sub { App::Ack::show_help_rgb(); exit; }, $extra_specs ? %{$extra_specs} : (), }; # arg_specs } sub _context_value { my $val = shift; # Contexts default to 2. return (!defined($val) || ($val < 0)) ? 2 : $val; } sub _process_other { my ( $opt, $extra_specs, $arg_sources ) = @_; my $argv_source; my $is_help_types_active; foreach my $source (@{$arg_sources}) { if ( $source->{name} eq 'ARGV' ) { $argv_source = $source->{contents}; last; } } if ( $argv_source ) { # This *should* always be true, but you never know... configure_parser( 'pass_through' ); Getopt::Long::GetOptionsFromArray( [ @{$argv_source} ], 'help-types' => \$is_help_types_active, ); } my $arg_specs = get_arg_spec( $opt, $extra_specs ); configure_parser(); foreach my $source (@{$arg_sources}) { my ( $source_name, $args ) = @{$source}{qw/name contents/}; my $args_for_source = { %{$arg_specs} }; if ( $source->{is_ackrc} ) { my $illegal = sub { my $name = shift; App::Ack::die( "Option --$name is forbidden in .ackrc files." ); }; $args_for_source = { %{$args_for_source}, 'output=s' => $illegal, 'match=s' => $illegal, }; } if ( $source->{project} ) { my $illegal = sub { my $name = shift; App::Ack::die( "Option --$name is forbidden in project .ackrc files." ); }; $args_for_source = { %{$args_for_source}, 'pager:s' => $illegal, }; } my $ret; if ( ref($args) ) { $ret = Getopt::Long::GetOptionsFromArray( $args, %{$args_for_source} ); } else { ( $ret, $source->{contents} ) = Getopt::Long::GetOptionsFromString( $args, %{$args_for_source} ); } if ( !$ret ) { if ( !$is_help_types_active ) { my $where = $source_name eq 'ARGV' ? 'on command line' : "in $source_name"; App::Ack::die( "Invalid option $where" ); } } if ( $opt->{noenv_seen} ) { App::Ack::die( "--noenv found in $source_name" ); } } # XXX We need to check on a -- in the middle of a non-ARGV source return; } sub _explode_sources { my ( $sources ) = @_; my @new_sources; my %opt; my $arg_spec = get_arg_spec( \%opt, {} ); my $dummy_sub = sub {}; my $add_type = sub { my ( undef, $arg ) = @_; if ( $arg =~ /(\w+)=/) { $arg_spec->{$1} = $dummy_sub; } else { ( $arg ) = split /:/, $arg; $arg_spec->{$arg} = $dummy_sub; } }; my $del_type = sub { my ( undef, $arg ) = @_; delete $arg_spec->{$arg}; }; configure_parser( 'pass_through' ); foreach my $source (@{$sources}) { my ( $name, $options ) = @{$source}{qw/name contents/}; if ( ref($options) ne 'ARRAY' ) { $source->{contents} = $options = [ Text::ParseWords::shellwords($options) ]; } for my $j ( 0 .. @{$options}-1 ) { next unless $options->[$j] =~ /^-/; my @chunk = ( $options->[$j] ); push @chunk, $options->[$j] while ++$j < @{$options} && $options->[$j] !~ /^-/; $j--; my @copy = @chunk; Getopt::Long::GetOptionsFromArray( [@chunk], 'type-add=s' => $add_type, 'type-set=s' => $add_type, 'type-del=s' => $del_type, %{$arg_spec} ); push @new_sources, { name => $name, contents => \@copy, }; } } return \@new_sources; } sub _compare_opts { my ( $a, $b ) = @_; my $first_a = $a->[0]; my $first_b = $b->[0]; $first_a =~ s/^--?//; $first_b =~ s/^--?//; return $first_a cmp $first_b; } sub _dump_options { my ( $sources ) = @_; $sources = _explode_sources($sources); my %opts_by_source; my @source_names; foreach my $source (@{$sources}) { my $name = $source->{name}; if ( not $opts_by_source{$name} ) { $opts_by_source{$name} = []; push @source_names, $name; } push @{$opts_by_source{$name}}, $source->{contents}; } foreach my $name (@source_names) { my $contents = $opts_by_source{$name}; say $name; say '=' x length($name); say ' ', join(' ', @{$_}) for sort { _compare_opts($a, $b) } @{$contents}; } return; } sub _remove_default_options_if_needed { my ( $sources ) = @_; my $default_index; foreach my $index ( 0 .. $#{$sources} ) { if ( $sources->[$index]{'name'} eq 'Defaults' ) { $default_index = $index; last; } } return $sources unless defined $default_index; my $should_remove = 0; configure_parser( 'no_auto_abbrev', 'pass_through' ); foreach my $index ( $default_index + 1 .. $#{$sources} ) { my $args = $sources->[$index]->{contents}; if (ref($args)) { Getopt::Long::GetOptionsFromArray( $args, 'ignore-ack-defaults' => \$should_remove, ); } else { ( undef, $sources->[$index]{contents} ) = Getopt::Long::GetOptionsFromString( $args, 'ignore-ack-defaults' => \$should_remove, ); } } return $sources unless $should_remove; my @copy = @{$sources}; splice @copy, $default_index, 1; return \@copy; } sub process_args { my $arg_sources = \@_; my %opt = ( pager => $ENV{ACK_PAGER_COLOR} || $ENV{ACK_PAGER}, ); $arg_sources = _remove_default_options_if_needed($arg_sources); # Check for --dump early. foreach my $source (@{$arg_sources}) { if ( $source->{name} eq 'ARGV' ) { my $dump; configure_parser( 'pass_through' ); Getopt::Long::GetOptionsFromArray( $source->{contents}, 'dump' => \$dump, ); if ( $dump ) { _dump_options($arg_sources); exit(0); } } } my $type_specs = _process_filetypes(\%opt, $arg_sources); _check_for_mutex_options( $type_specs ); _process_other(\%opt, $type_specs, $arg_sources); while ( @{$arg_sources} ) { my $source = shift @{$arg_sources}; my $args = $source->{contents}; # All of our sources should be transformed into an array ref if ( ref($args) ) { my $source_name = $source->{name}; if ( $source_name eq 'ARGV' ) { @ARGV = @{$args}; } elsif (@{$args}) { App::Ack::die( "Source '$source_name' has extra arguments!" ); } } else { App::Ack::die( 'The impossible has occurred!' ); } } my $filters = ($opt{filters} ||= []); # Throw the default filter in if no others are selected. if ( not grep { !$_->is_inverted() } @{$filters} ) { push @{$filters}, App::Ack::Filter::Default->new(); } return \%opt; } sub retrieve_arg_sources { my @arg_sources; my $noenv; my $ackrc; configure_parser( 'no_auto_abbrev', 'pass_through' ); Getopt::Long::GetOptions( 'noenv' => \$noenv, 'ackrc=s' => \$ackrc, ); my @files; if ( !$noenv ) { my $finder = App::Ack::ConfigFinder->new; @files = $finder->find_config_files; } if ( $ackrc ) { # We explicitly use open so we get a nice error message. # XXX This is a potential race condition!. if ( open my $fh, '<', $ackrc ) { close $fh; } else { App::Ack::die( "Unable to load ackrc '$ackrc': $!" ); } push( @files, { path => $ackrc } ); } push @arg_sources, { name => 'Defaults', contents => [ App::Ack::ConfigDefault::options_clean() ], }; foreach my $file ( @files) { my @lines = read_rcfile($file->{path}); if ( @lines ) { push @arg_sources, { name => $file->{path}, contents => \@lines, project => $file->{project}, is_ackrc => 1, }; } } push @arg_sources, { name => 'ARGV', contents => [ @ARGV ], }; return @arg_sources; } sub read_rcfile { my $file = shift; return unless defined $file && -e $file; my @lines; open( my $fh, '<', $file ) or App::Ack::die( "Unable to read $file: $!" ); while ( defined( my $line = <$fh> ) ) { chomp $line; $line =~ s/^\s+//; $line =~ s/\s+$//; next if $line eq ''; next if $line =~ /^\s*#/; push( @lines, $line ); } close $fh or App::Ack::die( "Unable to close $file: $!" ); return @lines; } # Verifies no mutex options were passed. Dies if they were. sub _check_for_mutex_options { my $type_specs = shift; my $mutex = mutex_options(); my ($raw,$used) = _options_used( $type_specs ); my @used = sort { lc $a cmp lc $b } keys %{$used}; for my $i ( @used ) { for my $j ( @used ) { next if $i eq $j; if ( $mutex->{$i}{$j} ) { my $x = $raw->[ $used->{$i} ]; my $y = $raw->[ $used->{$j} ]; App::Ack::die( "Options '$x' and '$y' can't be used together." ); } } } return; } # Processes the command line option and returns a hash of the options that were # used on the command line, using their full name. "--prox" shows up in the hash as "--proximate". sub _options_used { my $type_specs = shift; my %dummy_opt; my $real_spec = get_arg_spec( \%dummy_opt, $type_specs ); # The real argument parsing doesn't check for --type-add, --type-del or --type-set because # they get removed by the argument processing. We have to account for them here. my $sub_dummy = sub {}; $real_spec = { %{$real_spec}, 'type-add=s' => $sub_dummy, 'type-del=s' => $sub_dummy, 'type-set=s' => $sub_dummy, 'ignore-ack-defaults' => $sub_dummy, }; my %parsed; my @raw; my %spec_capture_parsed; my %spec_capture_raw; =pod We have to build two argument specs. To populate the C<%parsed> hash: Capture the arguments that the user has passed in, as parsed by the Getopt::Long::GetOptions function. Aliases are converted down to their short options. If a user passes "--proximate", Getopt::Long converts that to "-p" and we store it as "-p". To populate the C<@raw> array: Capture the arguments raw, without having been converted to their short options. If a user passes "--proximate", we store it in C<@raw> as "--proximate". =cut # Capture the %parsed hash. CAPTURE_PARSED: { my $parsed_pos = 0; my $sub_count = sub { my $arg = shift; $arg = "$arg"; $parsed{$arg} = $parsed_pos++; }; %spec_capture_parsed = ( '<>' => sub { $parsed_pos++ }, # Bump forward one pos for non-options. map { $_ => $sub_count } keys %{$real_spec} ); } # Capture the @raw array. CAPTURE_RAW: { my $raw_pos = 0; %spec_capture_raw = ( '<>' => sub { $raw_pos++ }, # Bump forward one pos for non-options. ); my $sub_count = sub { my $arg = shift; $arg = "$arg"; $raw[$raw_pos] = length($arg) == 1 ? "-$arg" : "--$arg"; $raw_pos++; }; for my $opt_spec ( keys %{$real_spec} ) { my $negatable; my $type; my $default; $negatable = ($opt_spec =~ s/!$//); if ( $opt_spec =~ s/(=[si])$// ) { $type = $1; } if ( $opt_spec =~ s/(:.+)$// ) { $default = $1; } my @aliases = split( /\|/, $opt_spec ); for my $alias ( @aliases ) { $alias .= $type if defined $type; $alias .= $default if defined $default; $alias .= '!' if $negatable; $spec_capture_raw{$alias} = $sub_count; } } } # Parse @ARGV twice, once with each capture spec. configure_parser( 'pass_through' ); # Ignore invalid options. Getopt::Long::GetOptionsFromArray( [@ARGV], %spec_capture_raw ); Getopt::Long::GetOptionsFromArray( [@ARGV], %spec_capture_parsed ); return (\@raw,\%parsed); } sub mutex_options { # This list is machine-generated by dev/crank-mutex. Do not modify it by hand. return { 1 => { m => 1, passthru => 1, }, A => { L => 1, c => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, }, B => { L => 1, c => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, }, C => { L => 1, c => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, }, H => { L => 1, f => 1, g => 1, l => 1, }, L => { A => 1, B => 1, C => 1, H => 1, L => 1, break => 1, c => 1, column => 1, f => 1, g => 1, group => 1, h => 1, heading => 1, l => 1, 'no-filename' => 1, o => 1, output => 1, p => 1, passthru => 1, 'show-types' => 1, v => 1, 'with-filename' => 1, }, break => { L => 1, c => 1, f => 1, g => 1, l => 1, }, c => { A => 1, B => 1, C => 1, L => 1, break => 1, column => 1, f => 1, g => 1, group => 1, heading => 1, m => 1, o => 1, output => 1, p => 1, passthru => 1, }, column => { L => 1, c => 1, f => 1, g => 1, l => 1, o => 1, output => 1, passthru => 1, v => 1, }, f => { A => 1, B => 1, C => 1, H => 1, L => 1, break => 1, c => 1, column => 1, f => 1, 'files-from' => 1, g => 1, group => 1, h => 1, heading => 1, l => 1, m => 1, match => 1, o => 1, output => 1, p => 1, passthru => 1, u => 1, v => 1, x => 1, }, 'files-from' => { f => 1, g => 1, x => 1, }, g => { A => 1, B => 1, C => 1, H => 1, L => 1, break => 1, c => 1, column => 1, f => 1, 'files-from' => 1, g => 1, group => 1, h => 1, heading => 1, l => 1, m => 1, match => 1, o => 1, output => 1, p => 1, passthru => 1, u => 1, x => 1, }, group => { L => 1, c => 1, f => 1, g => 1, l => 1, }, h => { L => 1, f => 1, g => 1, l => 1, }, heading => { L => 1, c => 1, f => 1, g => 1, l => 1, }, l => { A => 1, B => 1, C => 1, H => 1, L => 1, break => 1, column => 1, f => 1, g => 1, group => 1, h => 1, heading => 1, l => 1, 'no-filename' => 1, o => 1, output => 1, p => 1, passthru => 1, 'show-types' => 1, 'with-filename' => 1, }, m => { 1 => 1, c => 1, f => 1, g => 1, passthru => 1, }, match => { f => 1, g => 1, }, 'no-filename' => { L => 1, l => 1, }, o => { A => 1, B => 1, C => 1, L => 1, c => 1, column => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, 'show-types' => 1, v => 1, }, output => { A => 1, B => 1, C => 1, L => 1, c => 1, column => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, 'show-types' => 1, u => 1, v => 1, }, p => { A => 1, B => 1, C => 1, L => 1, c => 1, f => 1, g => 1, l => 1, o => 1, output => 1, p => 1, passthru => 1, }, passthru => { 1 => 1, A => 1, B => 1, C => 1, L => 1, c => 1, column => 1, f => 1, g => 1, l => 1, m => 1, o => 1, output => 1, p => 1, v => 1, }, 'show-types' => { L => 1, l => 1, o => 1, output => 1, }, u => { f => 1, g => 1, output => 1, }, v => { L => 1, column => 1, f => 1, o => 1, output => 1, passthru => 1, }, 'with-filename' => { L => 1, l => 1, }, x => { f => 1, 'files-from' => 1, g => 1, }, }; } # End of mutex_options() 1; # End of App::Ack::ConfigLoader ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack/Filter.pm��������������������������������������������������������������������0000644�0001751�0001751�00000004624�14023027176�014674� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack::Filter; use strict; use warnings; use App::Ack (); use App::Ack::Filter::Inverse (); my %filter_types; =head1 NAME App::Ack::Filter - Filter objects to filter files =head1 DESCRIPTION An abstract superclass that represents objects that can filter C<App::Ack::File> objects. App::Ack::Filter implementations are responsible for filtering filenames to be searched. =head1 SYNOPSIS # filter implementation package MyFilter; use strict; use warnings; use parent 'App::Ack::Filter'; sub filter { my ( $self, $file ) = @_; } BEGIN { App::Ack::Filter->register_filter('mine' => __PACKAGE__); } 1; # users App::Ack::Filter->create_filter('mine', @args); =head1 METHODS =head2 App::Ack::Filter->create_filter($type, @args) Creates a filter implementation, registered as C<$type>. C<@args> are provided as additional arguments to the implementation's constructor. =cut sub create_filter { my ( undef, $type, @args ) = @_; if ( my $package = $filter_types{$type} ) { return $package->new(@args); } my $allowed_types = join( ', ', sort keys %filter_types ); App::Ack::die( "Unknown filter type '$type'. Type must be one of: $allowed_types." ); } =head2 App::Ack::Filter->register_filter($type, $package) Registers a filter implementation package C<$package> under the name C<$type>. =cut sub register_filter { my ( undef, $type, $package ) = @_; $filter_types{$type} = $package; return; } =head2 $filter->filter( $file ) Must be implemented by filter implementations. Returns true if the filter passes, false otherwise. This method must B<not> alter the passed-in C<$file> object. =head2 $filter->invert() Returns a filter whose L</filter> method returns the opposite of this filter. =cut sub invert { my ( $self ) = @_; return App::Ack::Filter::Inverse->new( $self ); } =head2 $filter->is_inverted() Returns true if this filter is an inverted filter; false otherwise. =cut sub is_inverted { return 0; } =head2 $filter->to_string Converts the filter to a string. This method is also called implicitly by stringification. =cut sub to_string { return '(unimplemented to_string)'; } =head2 $filter->inspect Prints a human-readable debugging string for this filter. Useful for, you guessed it, debugging. =cut sub inspect { my ( $self ) = @_; return ref($self); } 1; ������������������������������������������������������������������������������������������������������������ack-v3.5.0/lib/App/Ack.pm���������������������������������������������������������������������������0000644�0001751�0001751�00000062022�14023040515�013433� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package App::Ack; use warnings; use strict; =head1 NAME App::Ack =head1 DESCRIPTION A container for functions for the ack program. =cut our $VERSION; our $COPYRIGHT; BEGIN { $VERSION = 'v3.5.0'; # Check https://beyondgrep.com/ for updates $COPYRIGHT = 'Copyright 2005-2021 Andy Lester.'; } our $STANDALONE = 0; our $ORIGINAL_PROGRAM_NAME; our $fh; BEGIN { $fh = *STDOUT; } our %types; our %type_wanted; our %mappings; our %ignore_dirs; our $is_filter_mode; our $output_to_pipe; our $is_windows; our $debug_nopens = 0; # Line ending, changes to "\0" if --print0. our $ors = "\n"; BEGIN { # These have to be checked before any filehandle diddling. $output_to_pipe = not -t *STDOUT; $is_filter_mode = -p STDIN; $is_windows = ($^O eq 'MSWin32'); } =head1 SYNOPSIS If you want to know about the F<ack> program, see the F<ack> file itself. No user-serviceable parts inside. F<ack> is all that should use this. =head1 FUNCTIONS =head2 warn( @_ ) Put out an ack-specific warning. =cut sub warn { return CORE::warn( _my_program(), ': ', @_, "\n" ); } =head2 die( @msgs ) Die in an ack-specific way. =cut sub die { return CORE::die( _my_program(), ': ', @_, "\n" ); } sub _my_program { require File::Basename; return File::Basename::basename( $0 ); } sub thpppt { my $y = q{_ /|,\\'!.x',=(www)=, U }; $y =~ tr/,x!w/\nOo_/; App::Ack::print( "$y ack $_[0]!\n" ); exit 0; } sub ackbar { my $x; $x = <<'_BAR'; 6?!I'7!I"?%+! 3~!I#7#I"7#I!?!+!="+"="+!:! 2?#I!7!I!?#I!7!I"+"=%+"=# 1?"+!?*+!=#~"=!+#?"="+! 0?"+!?"I"?&+!="~!=!~"=!+%="+" /I!+!?)+!?!+!=$~!=!~!="+!="+"?!="?! .?%I"?%+%='?!=#~$=" ,,!?%I"?(+$=$~!=#:"~$:!~! ,I!?!I!?"I"?!+#?"+!?!+#="~$:!~!:!~!:!,!:!,":#~! +I!?&+!="+!?#+$=!~":!~!:!~!:!,!:#,!:!,%:" *+!I!?!+$=!+!=!+!?$+#=!~":!~":#,$:",#:!,!:! *I!?"+!?!+!=$+!?#+#=#~":$,!:",!:!,&:" )I!?$=!~!=#+"?!+!=!+!=!~!="~!:!~":!,'.!,%:!~! (=!?"+!?!=!~$?"+!?!+!=#~"=",!="~$,$.",#.!:!=! (I"+"="~"=!+&=!~"=!~!,!~!+!=!?!+!?!=!I!?!+"=!.",!.!,":! %I$?!+!?!=%+!~!+#~!=!~#:#=!~!+!~!=#:!,%.!,!.!:" $I!?!=!?!I!+!?"+!=!~!=!~!?!I!?!=!+!=!~#:",!~"=!~!:"~!=!:",&:" '-/ $?!+!I!?"+"=!+"~!,!:"+#~#:#,"=!~"=!,!~!,!.",!:".!:! */! !I!t!'!s! !a! !g!r!e!p!!! !/! $+"=!+!?!+"~!=!:!~!:"I!+!,!~!=!:!~!,!:!,$:!~".&:"~!,# (-/ %~!=!~!=!:!.!+"~!:!,!.!,!~!=!:$.!,":!,!.!:!~!,!:!=!.#="~!,!:" ./! %=!~!?!+"?"+!=!~",!.!:!?!~!.!:!,!:!,#.!,!:","~!:!=!~!=!:",!~! ./! %+"~":!~!=#~!:!~!,!.!~!:",!~!=!~!.!:!,!.",!:!,":!=":!.!,!:!7! -/! %~",!:".#:!=!:!,!:"+!:!~!:!.!,!~!,!.#,!.!,$:"~!,":"~!=! */! &=!~!=#+!=!~",!.!:",#:#,!.",+:!,!.",!=!+!?! &~!=!~!=!~!:"~#:",!.!,#~!:!.!+!,!.",$.",$.#,!+!I!?! &~!="~!:!~":!~",!~!=!~":!,!:!~!,!:!,&.$,#."+!?!I!?!I! &~!=!~!=!+!,!:!~!:!=!,!:!~&:$,!.!,".!,".!,#."~!+!?$I! &~!=!~!="~!=!:!~":!,!~%:#,!:",!.!,#.",#I!7"I!?!+!?"I" &+!I!7!:#~"=!~!:!,!:"~$.!=!.!,!~!,$.#,!~!7!I#?!+!?"I"7! %7#?!+!~!:!=!~!=!~":!,!:"~":#.!,)7#I"?"I!7& %7#I!=":!=!~!:"~$:"~!:#,!:!,!:!~!:#,!7#I!?#7) $7$+!,!~!=#~!:!~!:!~$:#,!.!~!:!=!,":!7#I"?#7+=!?! $7#I!~!,!~#=!~!:"~!:!,!:!,#:!=!~",":!7$I!?#I!7*+!=!+" "I!7$I!,":!,!.!=":$,!:!,$:$7$I!+!?"I!7+?"I!7!I!7!,! !,!7%I!:",!."~":!,&.!,!:!~!I!7$I!+!?"I!7,?!I!7',! !7(,!.#~":!,%.!,!7%I!7!?#I"7,+!?!7* 7+:!,!~#,"=!7'I!?#I"7/+!7+ 77I!+!7!?!7!I"71+!7, _BAR return _pic_decode($x); } sub cathy { my $x = <<'CATHY'; 0+!--+! 0|! "C!H!O!C!O!L!A!T!E!!! !|! 0|! "C!H!O!C!O!L!A!T!E!!! !|! 0|! "C!H!O!C!O!L!A!T!E!!! !|! 0|! $A"C!K!!! $|! 0+!--+! 6\! 1:!,!.! ! 7\! /.!M!~!Z!M!~! 8\! /~!D! "M! ! 4.! $\! /M!~!.!8! +.!M# 4 0,!.! (\! .~!M!N! ,+!I!.!M!.! 3 /?!O!.!M!:! '\! .O!.! +~!Z!=!N!.! 4 ..! !D!Z!.!Z!.! '\! 9=!M".! 6 /.! !.!~!M".! '\! 8~! 9 4M!.! /.!7!N!M!.! F 4.! &:!M! !N"M# !M"N!M! #D!M&=! = :M!7!M#:! !~!M!7!,!$!M!:! #.! !O!N!.!M!:!M# ; 8Z!M"~!N!$!D!.!N!?! !I!N!.! (?!M! !M!,!D!M".! 9 (?!Z!M!N!:! )=!M!O!8!.!M!+!M! !M!,! !O!M! +,!M!.!M!~!Z!N!M!:! &:!~! 0 &8!7!.!~!M"D!M!,! &M!?!=!8! !M!,!O! !M!+! !+!O!.!M! $M#~! !.!8!M!Z!.!M! !O!M"Z! %:!~!M!Z!M!Z!.! + &:!M!7!,! *M!.!Z!M! !8"M!.!M!~! !.!M!.!=! #~!8!.!M! !7!M! "N!Z#I! !D!M!,!M!.! $."M!,! !M!.! * 2$!O! "N! !.!M!I! !7" "M! "+!O! !~!M! !d!O!.!7!I!M!.! !.!O!=!M!.! !M",!M!.! %.!$!O!D! + 1~!O! "M!+! !8!$! "M! "?!O! %Z!8!D!M!?!8!I!O!7!M! #M!.!M! "M",!M! 4 07!~! ".!8! !.!M! "I!+! !.!M! &Z!D!.!7!=!M! !:!.!M! #:!8"+! !.!+!8! !8! 3 /~!M! #N! !~!M!$! !.!M! !.!M" &~!M! "~!M!O! "D! $M! !8! "M!,!M!+!D!.! 1 #.! #?!M!N!.! #~!O! $M!.!7!$! "?" !?!~!M! '7!8!?!M!.!+!M"O! $?"$!D! !.!O! !$!7!I!.! 0 $,!M!:!O!?! ".! !?!=! $=!:!O! !M! "M! !M! !+!$! (.! +.!M! !M!.! !8! !+"Z!~! $:!M!$! !.! ' #.!8!.!I!$! $7!I! %M" !=!M! !~!M!D! "7!I! .I!O! %?!=!,!D! !,!M! !D!~!8!~! %D!M! ( #.!M"?! $=!O! %=!N! "8!.! !Z!M! #M!~! (M!:! #.!M" &O! !M!.! !?!,! !8!.!N!~! $8!N!M!,!.! % *$!O! &M!,! "O! !.!M!.! #M! (~!M( &O!.! !7! "M! !.!M!.!M!,! #.!M! !M! & )=!8!.! $.!M!O!.! "$!.!I!N! !I!M# (7!M(I! %D"Z!M! "=!I! "M! !M!:! #~!D! ' )D! &8!N!:! ".!O! !M!="M! "M! (7!M) %." !M!D!."M!.! !$!=! !M!,! + (M! &+!.!M! #Z!7!O!M!.!~!8! +,!M#D!?!M#D! #.!Z!M#,!Z!?! !~!N! "N!.! !M! + 'D!:! %$!D! !?! #M!Z! !8!.! !M"?!7!?!7! '+!I!D! !?!O!:!M!:! ":!M!:! !M!7".!M! "8!+! !:!D! !.!M! * %.!O!:! $.!O!+! !D!.! #M! "M!.!+!N!I!Z! "7!M!N!M!N!?!I!7!Z!=!M'D"~! #M!.!8!$! !:! !.!M! "N!?! !,!O! ) !.!?!M!:!M!I! %8!,! "M!.! #M! "N! !M!.! !M!.! !+!~! !.!M!.! ':!M! $M! $M!Z!$! !M!.! "D! "M! "?!M! ( !7!8! !+!I! ".! "$!=! ":!$! "+! !M!.! !O! !M!I!M".! !=!~! ",!O! '=!M! $$!,! #N!:! ":!8!.! !D!~! !,!M!.! !:!M!.! & !:!,!.! &Z" #D! !.!8!."M!.! !8!?!Z!M!.!M! #Z!~! !?!M!Z!.! %~!O!.!8!$!N!8!O!I!:!~! !+! #M!.! !.!M!.! !+!M! ".!~!M!+! $ !.! 'D!I! #?!M!.!M!,! !.!Z! !.!8! #M&O!I!?! (~!I!M"." !M!Z!.! !M!N!.! "+!$!.! "M!.! !M!?!.! "8!M! $ (O!8! $M! !M!.! ".!:! !+!=! #M! #.!M! !+" *$!M":!.! !M!~! "M!7! #M! #7!Z! "M"$!M!.! !.! # '$!Z! #.!7!+!M! $.!,! !+!:! #N! #.!M!.!+!M! +D!M! #=!N! ":!O! #=!M! #Z!D! $M!I! % $,! ".! $.!M" %$!.! !?!~! "+!7!." !.!M!,! !M! *,!N!M!.$M!?! "D!,! #M!.! #N! + ,M!Z! &M! "I!,! "M! %I!M! !?!=!.! (Z!8!M! $:!M!.! !,!M! $D! #.!M!.! ) +8!O! &.!8! "I!,! !~!M! &N!M! !M!D! '?!N!O!." $?!7! "?!~! #M!.! #I!D!.! ( 3M!,! "N!.! !D" &.!+!M!.! !M":!.":!M!7!M!D! 'M!.! "M!.! "M!,! $I! ) 3I! #M! "M!,! !:! &.!M" ".!,! !.!$!M!I! #.! !:! !.!M!?! "N!+! ".! / 1M!,! #.!M!8!M!=!.! +~!N"O!Z"~! *+!M!.! "M! 2 0.!M! &M!.! 8:! %.!M!Z! "M!=! *O!,! % 0?!$! &N! )." .,! %."M! ":!M!.! 0 0N!:! %?!O! #.! ..! &,! &.!D!,! "N!I! 0 CATHY return _pic_decode($x); } sub _pic_decode { my($compressed) = @_; $compressed =~ s/(.)(.)/$1x(ord($2)-32)/eg; App::Ack::print( $compressed ); exit 0; } =head2 show_help() Dumps the help page to the user. =cut sub show_help { App::Ack::print( <<"END_OF_HELP" ); Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] Search for PATTERN in each source file in the tree from the current directory on down. If any files or directories are specified, then only those files and directories are checked. ack may also search STDIN, but only if no file or directory arguments are specified, or if one of them is "-". Default switches may be specified in an .ackrc file. If you want no dependency on the environment, turn it off with --noenv. File select actions: -f Only print the files selected, without searching. The PATTERN must not be specified. -g Same as -f, but only select files matching PATTERN. File listing actions: -l, --files-with-matches Print filenames with at least one match -L, --files-without-matches Print filenames with no matches -c, --count Print filenames and count of matching lines Searching: -i, --ignore-case Ignore case distinctions in PATTERN -S, --[no]smart-case Ignore case distinctions in PATTERN, only if PATTERN contains no upper case. Ignored if -i or -I are specified. -I, --no-ignore-case Turns on case-sensitivity in PATTERN. Negates -i and --smart-case. -v, --invert-match Invert match: select non-matching lines -w, --word-regexp Force PATTERN to match only whole words -Q, --literal Quote all metacharacters; PATTERN is literal --range-start PATTERN Specify PATTERN as the start of a match range. --range-end PATTERN Specify PATTERN as the end of a match range. --match PATTERN Specify PATTERN explicitly. Typically omitted. Search output: --output=expr Output the evaluation of expr for each line (turns off text highlighting) -o Show only the part of a line matching PATTERN Same as --output='\$&' --passthru Print all lines, whether matching or not -m, --max-count=NUM Stop searching in each file after NUM matches -1 Stop searching after one match of any kind -H, --with-filename Print the filename for each match (default: on unless explicitly searching a single file) -h, --no-filename Suppress the prefixing filename on output --[no]column Show the column number of the first match -A NUM, --after-context=NUM Print NUM lines of trailing context after matching lines. -B NUM, --before-context=NUM Print NUM lines of leading context before matching lines. -C [NUM], --context[=NUM] Print NUM lines (default 2) of output context. --print0 Print null byte as separator between filenames, only works with -f, -g, -l, -L or -c. -s Suppress error messages about nonexistent or unreadable files. File presentation: --pager=COMMAND Pipes all ack output through COMMAND. For example, --pager="less -R". Ignored if output is redirected. --nopager Do not send output through a pager. Cancels any setting in ~/.ackrc, ACK_PAGER or ACK_PAGER_COLOR. --[no]heading Print a filename heading above each file's results. (default: on when used interactively) --[no]break Print a break between results from different files. (default: on when used interactively) --group Same as --heading --break --nogroup Same as --noheading --nobreak -p, --proximate=LINES Separate match output with blank lines unless they are within LINES lines from each other. -P, --proximate=0 Negates --proximate. --[no]underline Print a line of carets under the matched text. --[no]color, --[no]colour Highlight the matching text (default: on unless output is redirected, or on Windows) --color-filename=COLOR --color-match=COLOR --color-colno=COLOR --color-lineno=COLOR Set the color for filenames, matches, line and column numbers. --help-colors Show a list of possible color combinations. --help-rgb-colors Show a list of advanced RGB colors. --flush Flush output immediately, even when ack is used non-interactively (when output goes to a pipe or file). File finding: --sort-files Sort the found files lexically. --show-types Show which types each file has. --files-from=FILE Read the list of files to search from FILE. -x Read the list of files to search from STDIN. File inclusion/exclusion: --[no]ignore-dir=name Add/remove directory from list of ignored dirs --[no]ignore-directory=name Synonym for ignore-dir --ignore-file=FILTER:ARGS Add filter for ignoring files. -r, -R, --recurse Recurse into subdirectories (default: on) -n, --no-recurse No descending into subdirectories --[no]follow Follow symlinks. Default is off. File type inclusion/exclusion: -t X, --type=X Include only X files, where X is a filetype, e.g. python, html, markdown, etc -T X, --type=noX Exclude X files, where X is a filetype. -k, --known-types Include only files of types that ack recognizes. --help-types Display all known types, and how they're defined. File type specification: --type-set=TYPE:FILTER:ARGS Files with the given ARGS applied to the given FILTER are recognized as being of type TYPE. This replaces an existing definition for TYPE. --type-add=TYPE:FILTER:ARGS Files with the given ARGS applied to the given FILTER are recognized as being type TYPE. --type-del=TYPE Removes all filters associated with TYPE. Miscellaneous: --version Display version & copyright --[no]env Ignore environment variables and global ackrc files. --env is legal but redundant. --ackrc=filename Specify an ackrc file to use --ignore-ack-defaults Ignore default definitions included with ack. --create-ackrc Outputs a default ackrc for your customization to standard output. --dump Dump information on which options are loaded and where they're defined. --[no]filter Force ack to treat standard input as a pipe (--filter) or tty (--nofilter) --help This help --man Print the manual. --help-types Display all known types, and how they're defined. --help-colors Show a list of possible color combinations. --help-rgb-colors Show a list of advanced RGB colors. --thpppt Bill the Cat --bar The warning admiral --cathy Chocolate! Chocolate! Chocolate! Filter specifications: If FILTER is "ext", ARGS is a list of extensions checked against the file's extension. If FILTER is "is", ARGS must match the file's name exactly. If FILTER is "match", ARGS is matched as a case-insensitive regex against the filename. If FILTER is "firstlinematch", ARGS is matched as a regex the first line of the file's contents. Exit status is 0 if match, 1 if no match. ack's home page is at https://beyondgrep.com/ The full ack manual is available by running "ack --man". This is version $App::Ack::VERSION of ack. Run "ack --version" for full version info. END_OF_HELP return; } =head2 show_help_types() Display the filetypes help subpage. =cut sub show_help_types { App::Ack::print( <<'END_OF_HELP' ); Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] The following is the list of filetypes supported by ack. You can specify a filetype to include with -t TYPE or --type=TYPE. You can exclude a filetype with -T TYPE or --type=noTYPE. Note that some files may appear in multiple types. For example, a file called Rakefile is both Ruby (--type=ruby) and Rakefile (--type=rakefile). END_OF_HELP my @types = keys %App::Ack::mappings; my $maxlen = 0; for ( @types ) { $maxlen = length if $maxlen < length; } for my $type ( sort @types ) { next if $type =~ /^-/; # Stuff to not show my $ext_list = $mappings{$type}; if ( ref $ext_list ) { $ext_list = join( '; ', map { $_->to_string } @{$ext_list} ); } App::Ack::print( sprintf( " %-*.*s %s\n", $maxlen, $maxlen, $type, $ext_list ) ); } return; } =head2 show_help_colors() Display the colors help subpage. =cut sub show_help_colors { App::Ack::print( <<'END_OF_HELP' ); ack allows customization of the colors it uses when presenting matches onscreen. See the "ACK COLORS" section of the ack manual (ack --man). Here is a chart of how various color combinations appear: Each of the eight foreground colors, on each of the eight background colors or no background color, with and without the bold modifier. Run ack --help-rgb-colors for a chart of the RGB colors. END_OF_HELP _show_color_grid(); return; } =head2 show_help_rgb() Display the RGB help subpage. =cut sub show_help_rgb { App::Ack::print( <<'END_OF_HELP' ); ack allows customization of the colors it uses when presenting matches onscreen. See the "ACK COLORS" section of the ack manual (ack --man). Colors may be specified as "rggNNN" where "NNN" is a triplet of digits from 0 to 5 specifying the intensity of red, green and blue, respectively. Here is a grid of the 216 possible values for NNN. END_OF_HELP _show_rgb_grid(); App::Ack::say( 'Here are the 216 possible colors with the "reverse" modifier applied.', "\n" ); _show_rgb_grid( 'reverse' ); return; } sub _show_color_grid { my $cell_width = 7; my @fg_colors = qw( black red green yellow blue magenta cyan white ); my @bg_colors = map { "on_$_" } @fg_colors; App::Ack::say( _color_cell( '' ), map { _color_cell( $_ ) } @fg_colors ); App::Ack::say( _color_cell( '' ), map { _color_cell( '-' x $cell_width ) } @fg_colors ); for my $bg ( '', @bg_colors ) { App::Ack::say( _color_cell( '' ), ( map { _color_cell( $_, "$_ $bg" ) } @fg_colors ), $bg ); App::Ack::say( _color_cell( 'bold' ), ( map { _color_cell( $_, "bold $_ $bg" ) } @fg_colors ), $bg ); App::Ack::say(); } return; } sub _color_cell { my $text = shift; my $color = shift; my $cell_width = 7; $text = sprintf( '%-*s', $cell_width, $text ); return ($color ? Term::ANSIColor::colored( $text, $color ) : $text) . ' '; } sub _show_rgb_grid { my $modifier = shift // ''; my $grid = <<'HERE'; 544 544 544 544 544 554 554 554 554 554 454 454 454 454 454 455 455 455 455 455 445 445 445 445 445 545 545 545 545 545 533 533 533 543 543 553 553 553 453 453 353 353 353 354 354 355 355 355 345 345 335 335 335 435 435 535 535 535 534 534 511 521 531 531 541 551 451 451 351 251 151 152 152 153 154 155 145 145 135 125 115 215 215 315 415 515 514 514 513 512 500 510 520 530 540 550 450 350 250 150 050 051 052 053 054 055 045 035 025 015 005 105 205 305 405 505 504 503 502 501 400 410 410 420 430 440 340 340 240 140 040 041 041 042 043 044 034 034 024 014 004 104 104 204 304 404 403 403 402 401 300 300 310 320 320 330 330 230 130 130 030 030 031 032 032 033 033 023 013 013 003 003 103 203 203 303 303 302 301 301 200 200 200 210 210 220 220 220 120 120 020 020 020 021 021 022 022 022 012 012 002 002 002 102 102 202 202 202 201 201 100 100 100 100 100 110 110 110 110 110 010 010 010 010 010 011 011 011 011 011 001 001 001 001 001 101 101 101 101 101 522 522 532 542 542 552 552 452 352 352 252 252 253 254 254 255 255 245 235 235 225 225 325 425 425 525 525 524 523 523 411 411 421 431 431 441 441 341 241 241 141 141 142 143 143 144 144 134 124 124 114 114 214 314 314 414 414 413 412 412 422 422 432 432 432 442 442 442 342 342 242 242 242 243 243 244 244 244 234 234 224 224 224 324 324 424 424 424 423 423 311 311 311 321 321 331 331 331 231 231 131 131 131 132 132 133 133 133 123 123 113 113 113 213 213 313 313 313 312 312 433 433 433 433 433 443 443 443 443 443 343 343 343 343 343 344 344 344 344 344 334 334 334 334 334 434 434 434 434 434 211 211 211 211 211 221 221 221 221 221 121 121 121 121 121 122 122 122 122 122 112 112 112 112 112 212 212 212 212 212 322 322 322 322 322 332 332 332 332 332 232 232 232 232 232 233 233 233 233 233 223 223 223 223 223 323 323 323 323 323 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 555 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 333 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 222 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 HERE $grid =~ s/(\d\d\d)/Term::ANSIColor::colored( "$1", "$modifier rgb$1" )/eg; App::Ack::say( $grid ); return; } sub show_man { require Pod::Usage; Pod::Usage::pod2usage({ -input => $App::Ack::ORIGINAL_PROGRAM_NAME, -verbose => 2, -exitval => 0, }); return; } =head2 get_version_statement Returns the version information for ack. =cut sub get_version_statement { require Config; my $copyright = $App::Ack::COPYRIGHT; my $this_perl = $Config::Config{perlpath}; if ($^O ne 'VMS') { my $ext = $Config::Config{_exe}; $this_perl .= $ext unless $this_perl =~ m/$ext$/i; } my $perl_ver = sprintf( 'v%vd', $^V ); my $build_type = $App::Ack::STANDALONE ? 'standalone version' : 'standard build'; return <<"END_OF_VERSION"; ack $App::Ack::VERSION ($build_type) Running under Perl $perl_ver at $this_perl $copyright This program is free software. You may modify or distribute it under the terms of the Artistic License v2.0. END_OF_VERSION } sub print { print {$fh} @_; return; } sub say { print {$fh} @_, $ors; return; } sub print_blank_line { print {$fh} "\n"; return; } sub set_up_pager { my $command = shift; return if App::Ack::output_to_pipe(); my $pager; if ( not open( $pager, '|-', $command ) ) { App::Ack::die( qq{Unable to pipe to pager "$command": $!} ); } $fh = $pager; return; } =head2 output_to_pipe() Returns true if ack's input is coming from a pipe. =cut sub output_to_pipe { return $output_to_pipe; } =head2 exit_from_ack( $nmatches ) Exit from the application with the correct exit code. Returns with 0 if a match was found, otherwise with 1. The number of matches is handed in as the only argument. =cut sub exit_from_ack { my $nmatches = shift; my $rc = $nmatches ? 0 : 1; exit $rc; } =head2 show_types( $file ) Shows the filetypes associated with a given file. =cut sub show_types { my $file = shift; my @types = filetypes( $file ); my $arrow = @types ? ' => ' : ' =>'; App::Ack::say( $file->name, $arrow, join( ',', @types ) ); return; } sub filetypes { my ( $file ) = @_; my @matches; foreach my $k (keys %App::Ack::mappings) { my $filters = $App::Ack::mappings{$k}; foreach my $filter (@{$filters}) { # Clone the file. my $clone = $file->clone; if ( $filter->filter($clone) ) { push @matches, $k; last; } } } # https://metacpan.org/pod/distribution/Perl-Critic/lib/Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm @matches = sort @matches; return @matches; } sub is_lowercase { my $pat = shift; # The simplest case. return 1 if lc($pat) eq $pat; # If we have capitals, then go clean up any metacharacters that might have capitals. # Get rid of any literal backslashes first to avoid confusion. $pat =~ s/\\\\//g; my $metacharacter = qr/ |\\A # Beginning of string |\\B # Not word boundary |\\c[a-zA-Z] # Control characters |\\D # Non-digit character |\\G # End-of-match position of prior match |\\H # Not horizontal whitespace |\\K # Keep to the left |\\N(\{.+?\})? # Anything but \n, OR Unicode sequence |\\[pP]\{.+?\} # Named property and negation |\\[pP][A-Z] # Named property and negation, single-character shorthand |\\R # Linebreak |\\S # Non-space character |\\V # Not vertical whitespace |\\W # Non-word character |\\X # ??? |\\x[0-9A-Fa-f]{2} # Hex sequence |\\Z # End of string /x; $pat =~ s/$metacharacter//g; my $name = qr/[_A-Za-z][_A-Za-z0-9]*?/; # Eliminate named captures. $pat =~ s/\(\?'$name'//g; $pat =~ s/\(\?<$name>//g; # Eliminate named backreferences. $pat =~ s/\\k'$name'//g; $pat =~ s/\\k<$name>//g; $pat =~ s/\\k\{$name\}//g; # Now with those metacharacters and named things removed, now see if it's lowercase. return 1 if lc($pat) eq $pat; return 0; } 1; # End of App::Ack ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ack-v3.5.0/ack��������������������������������������������������������������������������������������0000755�0001751�0001751�00000221554�14023040515�011604� 0����������������������������������������������������������������������������������������������������ustar �andy����������������������������andy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl use strict; use warnings; our $VERSION = 'v3.5.0'; # Check https://beyondgrep.com/ for updates use 5.010001; use File::Spec (); use File::Next (); use Getopt::Long (); use App::Ack (); use App::Ack::ConfigLoader (); use App::Ack::File (); use App::Ack::Files (); use App::Ack::Filter (); use App::Ack::Filter::Default (); use App::Ack::Filter::Extension (); use App::Ack::Filter::FirstLineMatch (); use App::Ack::Filter::Inverse (); use App::Ack::Filter::Is (); use App::Ack::Filter::IsPath (); use App::Ack::Filter::Match (); use App::Ack::Filter::Collection (); # Global command-line options our $opt_1; our $opt_A; our $opt_B; our $opt_break; our $opt_color; our $opt_column; our $opt_debug; our $opt_c; our $opt_f; our $opt_g; our $opt_heading; our $opt_L; our $opt_l; our $opt_m; our $opt_output; our $opt_passthru; our $opt_p; our $opt_range_start; our $opt_range_end; our $opt_range_invert; our $opt_regex; our $opt_show_filename; our $opt_show_types; our $opt_underline; our $opt_v; # Flag if we need any context tracking. our $is_tracking_context; # The regex that we search for in each file. our $search_re; # Special /m version of our $search_re. our $scan_re; our @special_vars_used_by_opt_output; our $using_ranges; # Internal stats for debugging. our %stats; MAIN: { $App::Ack::ORIGINAL_PROGRAM_NAME = $0; $0 = join(' ', 'ack', $0); $App::Ack::ors = "\n"; if ( $App::Ack::VERSION ne $main::VERSION ) { App::Ack::die( "Program/library version mismatch\n\t$0 is $main::VERSION\n\t$INC{'App/Ack.pm'} is $App::Ack::VERSION" ); } # Do preliminary arg checking; my $env_is_usable = 1; for my $arg ( @ARGV ) { last if ( $arg eq '--' ); # Get the --thpppt, --bar, --cathy and --man checking out of the way. $arg =~ /^--th[pt]+t+$/ and App::Ack::thpppt($arg); $arg eq '--bar' and App::Ack::ackbar(); $arg eq '--cathy' and App::Ack::cathy(); # See if we want to ignore the environment. (Don't tell Al Gore.) $arg eq '--env' and $env_is_usable = 1; $arg eq '--noenv' and $env_is_usable = 0; } if ( $env_is_usable ) { if ( $ENV{ACK_OPTIONS} ) { App::Ack::warn( 'WARNING: ack no longer uses the ACK_OPTIONS environment variable. Use an ackrc file instead.' ); } } else { my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV ); delete @ENV{@keys}; } # Load colors my $modules_loaded_ok = eval 'use Term::ANSIColor 1.10 (); 1;'; if ( $modules_loaded_ok && $App::Ack::is_windows ) { $modules_loaded_ok = eval 'use Win32::Console::ANSI; 1;'; } if ( $modules_loaded_ok ) { $ENV{ACK_COLOR_MATCH} ||= 'black on_yellow'; $ENV{ACK_COLOR_FILENAME} ||= 'bold green'; $ENV{ACK_COLOR_LINENO} ||= 'bold yellow'; $ENV{ACK_COLOR_COLNO} ||= 'bold yellow'; } App::Ack::ConfigLoader::configure_parser( 'no_auto_abbrev', 'pass_through' ); Getopt::Long::GetOptions( help => sub { App::Ack::show_help(); exit; }, version => sub { App::Ack::print( App::Ack::get_version_statement() ); exit; }, man => sub { App::Ack::show_man(); }, ); if ( !@ARGV ) { App::Ack::show_help(); exit 1; } my @arg_sources = App::Ack::ConfigLoader::retrieve_arg_sources(); my $opt = App::Ack::ConfigLoader::process_args( @arg_sources ); $opt_1 = $opt->{1}; $opt_A = $opt->{A}; $opt_B = $opt->{B}; $opt_break = $opt->{break}; $opt_c = $opt->{c}; $opt_color = $opt->{color}; $opt_column = $opt->{column}; $opt_debug = $opt->{debug}; $opt_f = $opt->{f}; $opt_g = $opt->{g}; $opt_heading = $opt->{heading}; $opt_L = $opt->{L}; $opt_l = $opt->{l}; $opt_m = $opt->{m}; $opt_output = $opt->{output}; $opt_p = $opt->{p}; $opt_passthru = $opt->{passthru}; $opt_range_start = $opt->{range_start}; $opt_range_end = $opt->{range_end}; $opt_range_invert = $opt->{range_invert}; $opt_regex = $opt->{regex}; $opt_show_filename = $opt->{show_filename}; $opt_show_types = $opt->{show_types}; $opt_underline = $opt->{underline}; $opt_v = $opt->{v}; if ( $opt_show_types && not( $opt_f || $opt_g ) ) { App::Ack::die( '--show-types can only be used with -f or -g.' ); } if ( $opt_range_start ) { ($opt_range_start, undef) = build_regex( $opt_range_start, {} ); } if ( $opt_range_end ) { ($opt_range_end, undef) = build_regex( $opt_range_end, {} ); } $using_ranges = $opt_range_start || $opt_range_end; $App::Ack::report_bad_filenames = !$opt->{s}; $App::Ack::ors = $opt->{print0} ? "\0" : "\n"; if ( !defined($opt_color) && !$opt_g ) { my $windows_color = 1; if ( $App::Ack::is_windows ) { $windows_color = eval { require Win32::Console::ANSI; }; } $opt_color = !App::Ack::output_to_pipe() && $windows_color; } $opt_heading //= !App::Ack::output_to_pipe(); $opt_break //= !App::Ack::output_to_pipe(); if ( defined($opt->{H}) || defined($opt->{h}) ) { $opt_show_filename = $opt->{show_filename} = $opt->{H} && !$opt->{h}; } if ( defined $opt_output ) { # Expand out \t, \n and \r. $opt_output =~ s/\\n/\n/g; $opt_output =~ s/\\r/\r/g; $opt_output =~ s/\\t/\t/g; my @supported_special_variables = ( 1..9, qw( _ . ` & ' + f ) ); @special_vars_used_by_opt_output = grep { $opt_output =~ /\$$_/ } @supported_special_variables; # If the $opt_output contains $&, $` or $', those vars won't be # captured until they're used at least once in the program. # Do the eval to make this happen. for my $i ( @special_vars_used_by_opt_output ) { if ( $i eq q{&} || $i eq q{'} || $i eq q{`} ) { no warnings; # They will be undef, so don't warn. eval qq{"\$$i"}; ## no critic ( ErrorHandling::RequireCheckingReturnValueOfEval ) } } } # Set up file filters. my $files; if ( $App::Ack::is_filter_mode && !$opt->{files_from} ) { # probably -x $files = App::Ack::Files->from_stdin(); $opt_regex //= shift @ARGV; ($search_re, $scan_re) = build_regex( $opt_regex, $opt ); $stats{search_re} = $search_re; $stats{scan_re} = $scan_re; } else { if ( $opt_f ) { # No need to check for regex, since mutex options are handled elsewhere. } else { $opt_regex //= shift @ARGV; ($search_re, $scan_re) = build_regex( $opt_regex, $opt ); $stats{search_re} = $search_re; $stats{scan_re} = $scan_re; } # XXX What is this checking for? if ( $search_re && $search_re =~ /\n/ ) { App::Ack::exit_from_ack( 0 ); } my @start; if ( not defined $opt->{files_from} ) { @start = @ARGV; } if ( !exists($opt->{show_filename}) ) { unless(@start == 1 && !(-d $start[0])) { $opt_show_filename = $opt->{show_filename} = 1; } } if ( defined $opt->{files_from} ) { $files = App::Ack::Files->from_file( $opt, $opt->{files_from} ); exit 1 unless $files; } else { @start = ('.') unless @start; foreach my $target (@start) { if ( !-e $target && $App::Ack::report_bad_filenames) { App::Ack::warn( "$target: No such file or directory" ); } } $opt->{file_filter} = _compile_file_filter($opt, \@start); $opt->{descend_filter} = _compile_descend_filter($opt); $files = App::Ack::Files->from_argv( $opt, \@start ); } } App::Ack::set_up_pager( $opt->{pager} ) if defined $opt->{pager}; my $nmatches; if ( $opt_f || $opt_g ) { $nmatches = file_loop_fg( $files ); } elsif ( $opt_c ) { $nmatches = file_loop_c( $files ); } elsif ( $opt_l || $opt_L ) { $nmatches = file_loop_lL( $files ); } else { $nmatches = file_loop_normal( $files ); } if ( $opt_debug ) { require List::Util; my @stats = qw( search_re scan_re prescans linescans filematches linematches ); my $width = List::Util::max( map { length } @stats ); for my $stat ( @stats ) { App::Ack::warn( sprintf( '%-*.*s = %s', $width, $width, $stat, $stats{$stat} // 'undef' ) ); } } close $App::Ack::fh; App::Ack::exit_from_ack( $nmatches ); } # End of MAIN sub file_loop_fg { my $files = shift; my $nmatches = 0; while ( defined( my $file = $files->next ) ) { if ( $opt_show_types ) { App::Ack::show_types( $file ); } elsif ( $opt_g ) { print_line_with_options( undef, $file->name, 0, $App::Ack::ors ); } else { App::Ack::say( $file->name ); } ++$nmatches; last if defined($opt_m) && ($nmatches >= $opt_m); } return $nmatches; } sub file_loop_c { my $files = shift; my $total_count = 0; while ( defined( my $file = $files->next ) ) { my $matches_for_this_file = count_matches_in_file( $file ); if ( not $opt_show_filename ) { $total_count += $matches_for_this_file; next; } if ( !$opt_l || $matches_for_this_file > 0 ) { if ( $opt_show_filename ) { my $display_filename = $file->name; if ( $opt_color ) { $display_filename = Term::ANSIColor::colored($display_filename, $ENV{ACK_COLOR_FILENAME}); } App::Ack::say( $display_filename, ':', $matches_for_this_file ); } else { App::Ack::say( $matches_for_this_file ); } } } if ( !$opt_show_filename ) { App::Ack::say( $total_count ); } return; } sub file_loop_lL { my $files = shift; my $nmatches = 0; while ( defined( my $file = $files->next ) ) { my $is_match = count_matches_in_file( $file, 1 ); if ( $opt_L ? !$is_match : $is_match ) { App::Ack::say( $file->name ); ++$nmatches; last if $opt_1; last if defined($opt_m) && ($nmatches >= $opt_m); } } return $nmatches; } sub _compile_descend_filter { my ( $opt ) = @_; my $idirs = 0; my $dont_ignore_dirs = 0; for my $filter (@{$opt->{idirs} || []}) { if ($filter->is_inverted()) { $dont_ignore_dirs++; } else { $idirs++; } } # If we have one or more --noignore-dir directives, we can't ignore # entire subdirectory hierarchies, so we return an "accept all" # filter and scrutinize the files more in _compile_file_filter. return if $dont_ignore_dirs; return unless $idirs; $idirs = $opt->{idirs}; return sub { my $file = App::Ack::File->new($File::Next::dir); return !grep { $_->filter($file) } @{$idirs}; }; } sub _compile_file_filter { my ( $opt, $start ) = @_; my $ifiles_filters = $opt->{ifiles}; my $filters = $opt->{'filters'} || []; my $direct_filters = App::Ack::Filter::Collection->new(); my $inverse_filters = App::Ack::Filter::Collection->new(); foreach my $filter (@{$filters}) { if ($filter->is_inverted()) { # We want to check if files match the uninverted filters $inverse_filters->add($filter->invert()); } else { $direct_filters->add($filter); } } my %is_member_of_starting_set = map { (get_file_id($_) => 1) } @{$start}; my @ignore_dir_filter = @{$opt->{idirs} || []}; my @is_inverted = map { $_->is_inverted() } @ignore_dir_filter; # This depends on InverseFilter->invert returning the original filter (for optimization). @ignore_dir_filter = map { $_->is_inverted() ? $_->invert() : $_ } @ignore_dir_filter; my $dont_ignore_dir_filter = grep { $_ } @is_inverted; my $previous_dir = ''; my $previous_dir_ignore_result; return sub { if ( $opt_g ) { if ( $File::Next::name =~ /$search_re/o ) { return 0 if $opt_v; } else { return 0 if !$opt_v; } } # ack always selects files that are specified on the command # line, regardless of filetype. If you want to ack a JPEG, # and say "ack foo whatever.jpg" it will do it for you. return 1 if $is_member_of_starting_set{ get_file_id($File::Next::name) }; if ( $dont_ignore_dir_filter ) { if ( $previous_dir eq $File::Next::dir ) { if ( $previous_dir_ignore_result ) { return 0; } } else { my @dirs = File::Spec->splitdir($File::Next::dir); my $is_ignoring = 0; for ( my $i = 0; $i < @dirs; $i++) { my $dir_rsrc = App::Ack::File->new(File::Spec->catfile(@dirs[0 .. $i])); my $j = 0; for my $filter (@ignore_dir_filter) { if ( $filter->filter($dir_rsrc) ) { $is_ignoring = !$is_inverted[$j]; } $j++; } } $previous_dir = $File::Next::dir; $previous_dir_ignore_result = $is_ignoring; if ( $is_ignoring ) { return 0; } } } # Ignore named pipes found in directory searching. Named # pipes created by subprocesses get specified on the command # line, so the rule of "always select whatever is on the # command line" wins. return 0 if -p $File::Next::name; # We can't handle unreadable filenames; report them. if ( not -r _ ) { use filetest 'access'; if ( not -R $File::Next::name ) { if ( $App::Ack::report_bad_filenames ) { App::Ack::warn( "${File::Next::name}: cannot open file for reading" ); } return 0; } } my $file = App::Ack::File->new($File::Next::name); if ( $ifiles_filters && $ifiles_filters->filter($file) ) { return 0; } my $match_found = $direct_filters->filter($file); # Don't bother invoking inverse filters unless we consider the current file a match. if ( $match_found && $inverse_filters->filter( $file ) ) { $match_found = 0; } return $match_found; }; } # Returns a (fairly) unique identifier for a file. # Use this function to compare two files to see if they're # equal (ie. the same file, but with a different path/links/etc). sub get_file_id { my ( $filename ) = @_; if ( $App::Ack::is_windows ) { return File::Next::reslash( $filename ); } else { # XXX Is this the best method? It always hits the FS. if ( my ( $dev, $inode ) = (stat($filename))[0, 1] ) { return join(':', $dev, $inode); } else { # XXX This could be better. return $filename; } } } # Returns a regex object based on a string and command-line options. # Dies when the regex $str is undefined (i.e. not given on command line). sub build_regex { my $str = shift; my $opt = shift; defined $str or App::Ack::die( 'No regular expression found.' ); if ( !$opt->{Q} ) { # Compile the regex to see if it dies or throws warnings. local $SIG{__WARN__} = sub { die @_ }; # Anything that warns becomes a die. my $scratch_regex = eval { qr/$str/ }; if ( not $scratch_regex ) { my $err = $@; chomp $err; if ( $err =~ m{^(.+?); marked by <-- HERE in m/(.+?) <-- HERE} ) { my ($why, $where) = ($1,$2); my $pointy = ' ' x (6+length($where)) . '^---HERE'; App::Ack::die( "Invalid regex '$str'\nRegex: $str\n$pointy $why" ); } else { App::Ack::die( "Invalid regex '$str'\n$err" ); } } } # Check for lowercaseness before we do any modifications. my $regex_is_lc = App::Ack::is_lowercase( $str ); $str = quotemeta( $str ) if $opt->{Q}; my $scan_str = $str; # Whole words only. if ( $opt->{w} ) { my $ok = 1; if ( $str =~ /^\\[wd]/ ) { # Explicit \w is good. } else { # Can start with \w, (, [ or dot. if ( $str !~ /^[\w\(\[\.]/ ) { $ok = 0; } } # Can end with \w, }, ), ], +, *, or dot. if ( $str !~ /[\w\}\)\]\+\*\?\.]$/ ) { $ok = 0; } # ... unless it's escaped. elsif ( $str =~ /\\[\}\)\]\+\*\?\.]$/ ) { $ok = 0; } if ( !$ok ) { App::Ack::die( '-w will not do the right thing if your regex does not begin and end with a word character.' ); } if ( $str =~ /^\w+$/ ) { # No need for fancy regex if it's a simple word. $str = sprintf( '\b(?:%s)\b', $str ); } else { $str = sprintf( '(?:^|\b|\s)\K(?:%s)(?=\s|\b|$)', $str ); } } if ( $opt->{i} || ($opt->{S} && $regex_is_lc) ) { $_ = "(?i)$_" for ( $str, $scan_str ); } my $scan_regex = undef; my $regex = eval { qr/$str/ }; if ( $regex ) { if ( $scan_str !~ /\$/ ) { # No line_scan is possible if there's a $ in the regex. $scan_regex = eval { qr/$scan_str/m }; } } else { my $err = $@; chomp $err; App::Ack::die( "Invalid regex '$str':\n $err" ); } return ($regex, $scan_regex); } my $match_colno; { # Number of context lines my $n_before_ctx_lines; my $n_after_ctx_lines; # Array to keep track of lines that might be required for a "before" context my @before_context_buf; # Position to insert next line in @before_context_buf my $before_context_pos; # Number of "after" context lines still pending my $after_context_pending; # Number of latest line that got printed my $printed_lineno; my $is_first_match; state $has_printed_from_any_file = 0; sub file_loop_normal { my $files = shift; $n_before_ctx_lines = $opt_output ? 0 : ($opt_B || 0); $n_after_ctx_lines = $opt_output ? 0 : ($opt_A || 0); @before_context_buf = (undef) x $n_before_ctx_lines; $before_context_pos = 0; $is_tracking_context = $n_before_ctx_lines || $n_after_ctx_lines; $is_first_match = 1; my $nmatches = 0; while ( defined( my $file = $files->next ) ) { if ($is_tracking_context) { $printed_lineno = 0; $after_context_pending = 0; if ( $opt_heading ) { $is_first_match = 1; } } my $needs_line_scan = 1; if ( !$opt_passthru && !$opt_v ) { $stats{prescans}++; if ( $file->may_be_present( $scan_re ) ) { $file->reset(); } else { $needs_line_scan = 0; } } if ( $needs_line_scan ) { $stats{linescans}++; $nmatches += print_matches_in_file( $file ); } last if $opt_1 && $nmatches; } return $nmatches; } sub print_matches_in_file { my $file = shift; my $max_count = $opt_m || -1; # Go negative for no limit so it can never reduce to 0. my $nmatches = 0; my $filename = $file->name; my $has_printed_from_this_file = 0; my $fh = $file->open; if ( !$fh ) { if ( $App::Ack::report_bad_filenames ) { App::Ack::warn( "$filename: $!" ); } return 0; } my $display_filename = $filename; if ( $opt_show_filename && $opt_heading && $opt_color ) { $display_filename = Term::ANSIColor::colored($display_filename, $ENV{ACK_COLOR_FILENAME}); } # Check for context before the main loop, so we don't pay for it if we don't need it. if ( $is_tracking_context ) { local $_ = undef; $after_context_pending = 0; my $in_range = range_setup(); while ( <$fh> ) { chomp; $match_colno = undef; $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); my $does_match; if ( $in_range ) { if ( $opt_v ) { $does_match = !/$search_re/o; } else { if ( $does_match = /$search_re/o ) { # @- = @LAST_MATCH_START # @+ = @LAST_MATCH_END $match_colno = $-[0] + 1; } } } if ( $does_match && $max_count ) { if ( !$has_printed_from_this_file ) { $stats{filematches}++; if ( $opt_break && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } if ( $opt_show_filename && $opt_heading ) { App::Ack::say( $display_filename ); } } print_line_with_context( $filename, $_, $. ); $has_printed_from_this_file = 1; $stats{linematches}++; $nmatches++; $max_count--; } else { if ( $after_context_pending ) { # Disable $opt_column since there are no matches in the context lines. local $opt_column = 0; print_line_with_options( $filename, $_, $., '-' ); --$after_context_pending; } elsif ( $n_before_ctx_lines ) { # Save line for "before" context. $before_context_buf[$before_context_pos] = $_; $before_context_pos = ($before_context_pos+1) % $n_before_ctx_lines; } } $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); last if ($max_count == 0) && ($after_context_pending == 0); } } elsif ( $opt_passthru ) { local $_ = undef; my $in_range = range_setup(); while ( <$fh> ) { chomp; $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); $match_colno = undef; if ( $in_range && ($opt_v xor /$search_re/o) ) { if ( !$opt_v ) { $match_colno = $-[0] + 1; } if ( !$has_printed_from_this_file ) { if ( $opt_break && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } if ( $opt_show_filename && $opt_heading ) { App::Ack::say( $display_filename ); } } print_line_with_options( $filename, $_, $., ':' ); $has_printed_from_this_file = 1; $nmatches++; $max_count--; } else { if ( $opt_break && !$has_printed_from_this_file && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } print_line_with_options( $filename, $_, $., '-', 1 ); $has_printed_from_this_file = 1; } $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); last if $max_count == 0; } } elsif ( $opt_v ) { local $_ = undef; $match_colno = undef; my $in_range = range_setup(); while ( <$fh> ) { chomp; $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); if ( $in_range ) { if ( !/$search_re/o ) { if ( !$has_printed_from_this_file ) { if ( $opt_break && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } if ( $opt_show_filename && $opt_heading ) { App::Ack::say( $display_filename ); } } print_line_with_context( $filename, $_, $. ); $has_printed_from_this_file = 1; $nmatches++; $max_count--; } } $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); last if $max_count == 0; } } else { # Normal search: No context, no -v, no --passthru local $_ = undef; my $last_match_lineno; my $in_range = range_setup(); while ( <$fh> ) { chomp; $in_range = 1 if ( $using_ranges && !$in_range && $opt_range_start && /$opt_range_start/o ); if ( $in_range ) { $match_colno = undef; if ( /$search_re/o ) { $match_colno = $-[0] + 1; if ( !$has_printed_from_this_file ) { $stats{filematches}++; if ( $opt_break && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } if ( $opt_show_filename && $opt_heading ) { App::Ack::say( $display_filename ); } } if ( $opt_p ) { if ( $last_match_lineno ) { if ( $. > $last_match_lineno + $opt_p ) { App::Ack::print_blank_line(); } } elsif ( !$opt_break && $has_printed_from_any_file ) { App::Ack::print_blank_line(); } } s/[\r\n]+$//; print_line_with_options( $filename, $_, $., ':' ); $has_printed_from_this_file = 1; $nmatches++; $stats{linematches}++; $max_count--; $last_match_lineno = $.; } } $in_range = 0 if ( $using_ranges && $in_range && $opt_range_end && /$opt_range_end/o ); last if $max_count == 0; } } return $nmatches; } sub print_line_with_options { my ( $filename, $line, $lineno, $separator, $skip_coloring ) = @_; $has_printed_from_any_file = 1; $printed_lineno = $lineno; my @line_parts; if ( $opt_show_filename && defined($filename) ) { my $colno; $colno = get_match_colno() if $opt_column; if ( $opt_color ) { $filename = Term::ANSIColor::colored( $filename, $ENV{ACK_COLOR_FILENAME} ); $lineno = Term::ANSIColor::colored( $lineno, $ENV{ACK_COLOR_LINENO} ); $colno = Term::ANSIColor::colored( $colno, $ENV{ACK_COLOR_COLNO} ) if $opt_column; } if ( $opt_heading ) { push @line_parts, $lineno; } else { push @line_parts, $filename, $lineno; } push @line_parts, $colno if $opt_column; } if ( $opt_output ) { while ( $line =~ /$search_re/og ) { my $output = $opt_output; if ( @special_vars_used_by_opt_output ) { no strict; # Stash copies of the special variables because we can't rely # on them not changing in the process of doing the s///. my %keep = map { ($_ => ${$_} // '') } @special_vars_used_by_opt_output; $keep{_} = $line if exists $keep{_}; # Manually set it because $_ gets reset in a map. $keep{f} = $filename if exists $keep{f}; my $special_vars_used_by_opt_output = join( '', @special_vars_used_by_opt_output ); $output =~ s/\$([$special_vars_used_by_opt_output])/$keep{$1}/ego; } App::Ack::say( join( $separator, @line_parts, $output ) ); } } else { my $underline = ''; # We have to do underlining before any highlighting because highlighting modifies string length. if ( $opt_underline && !$skip_coloring ) { while ( $line =~ /$search_re/og ) { my $match_start = $-[0] // next; my $match_end = $+[0]; my $match_length = $match_end - $match_start; last if $match_length <= 0; my $spaces_needed = $match_start - length $underline; $underline .= (' ' x $spaces_needed); $underline .= ('^' x $match_length); } } if ( $opt_color && !$skip_coloring ) { my $highlighted = 0; # If highlighted, need to escape afterwards. while ( $line =~ /$search_re/og ) { my $match_start = $-[0] // next; my $match_end = $+[0]; my $match_length = $match_end - $match_start; last if $match_length <= 0; my $substring = substr( $line, $match_start, $match_length ); my $substitution = Term::ANSIColor::colored( $substring, $ENV{ACK_COLOR_MATCH} ); # Fourth argument replaces the string specified by the first three. substr( $line, $match_start, $match_length, $substitution ); # Move the offset of where /g left off forward the number of spaces of highlighting. pos($line) = $match_end + (length( $substitution ) - length( $substring )); $highlighted = 1; } # Reset formatting and delete everything to the end of the line. $line .= "\e[0m\e[K" if $highlighted; } push @line_parts, $line; App::Ack::say( join( $separator, @line_parts ) ); # Print the underline, if appropriate. if ( $underline ne '' ) { # Figure out how many spaces are used per line for the ANSI coloring. state $chars_used_by_coloring; if ( !defined($chars_used_by_coloring) ) { $chars_used_by_coloring = 0; if ( $opt_color ) { my $len_fn = sub { length( Term::ANSIColor::colored( 'x', $ENV{$_[0]} ) ) - 1 }; $chars_used_by_coloring += $len_fn->('ACK_COLOR_FILENAME') unless $opt_heading; $chars_used_by_coloring += $len_fn->('ACK_COLOR_LINENO'); $chars_used_by_coloring += $len_fn->('ACK_COLOR_COLNO') if $opt_column; } } pop @line_parts; # Leave only the stuff on the left. if ( @line_parts ) { my $stuff_on_the_left = join( $separator, @line_parts ); my $spaces_needed = length($stuff_on_the_left) - $chars_used_by_coloring + 1; App::Ack::print( ' ' x $spaces_needed ); } App::Ack::say( $underline ); } } return; } sub print_line_with_context { my ( $filename, $matching_line, $lineno ) = @_; $matching_line =~ s/[\r\n]+$//; # Check if we need to print context lines first. if ( $opt_A || $opt_B ) { my $before_unprinted = $lineno - $printed_lineno - 1; if ( !$is_first_match && ( !$printed_lineno || $before_unprinted > $n_before_ctx_lines ) ) { App::Ack::say( '--' ); } # We want at most $n_before_ctx_lines of context. if ( $before_unprinted > $n_before_ctx_lines ) { $before_unprinted = $n_before_ctx_lines; } while ( $before_unprinted > 0 ) { my $line = $before_context_buf[($before_context_pos - $before_unprinted + $n_before_ctx_lines) % $n_before_ctx_lines]; chomp $line; # Disable $opt->{column} since there are no matches in the context lines. local $opt_column = 0; print_line_with_options( $filename, $line, $lineno-$before_unprinted, '-' ); $before_unprinted--; } } print_line_with_options( $filename, $matching_line, $lineno, ':' ); # We want to get the next $n_after_ctx_lines printed. $after_context_pending = $n_after_ctx_lines; $is_first_match = 0; return; } } sub get_match_colno { return $match_colno; } sub count_matches_in_file { my $file = shift; my $bail = shift; # True if we're just checking for existence. my $nmatches = 0; my $do_scan = 1; if ( !$file->open() ) { $do_scan = 0; if ( $App::Ack::report_bad_filenames ) { App::Ack::warn( $file->name . ": $!" ); } } else { if ( !$opt_v ) { if ( !$file->may_be_present( $scan_re ) ) { $do_scan = 0; } } } if ( $do_scan ) { $file->reset(); my $in_range = range_setup(); my $fh = $file->{fh}; if ( $using_ranges ) { while ( <$fh> ) { chomp; $in_range = 1 if ( !$in_range && $opt_range_start && /$opt_range_start/o ); if ( $in_range ) { if ( /$search_re/o xor $opt_v ) { ++$nmatches; last if $bail; } } $in_range = 0 if ( $in_range && $opt_range_end && /$opt_range_end/o ); } } else { while ( <$fh> ) { chomp; if ( /$search_re/o xor $opt_v ) { ++$nmatches; last if $bail; } } } } $file->close; return $nmatches; } sub range_setup { return !$using_ranges || (!$opt_range_start && $opt_range_end); } =pod =encoding UTF-8 =head1 NAME ack - grep-like text finder =head1 SYNOPSIS ack [options] PATTERN [FILE...] ack -f [options] [DIRECTORY...] =head1 DESCRIPTION ack is designed as an alternative to F<grep> for programmers. ack searches the named input FILEs or DIRECTORYs for lines containing a match to the given PATTERN. By default, ack prints the matching lines. If no FILE or DIRECTORY is given, the current directory will be searched. PATTERN is a Perl regular expression. Perl regular expressions are commonly found in other programming languages, but for the particulars of their behavior, please consult L<perlreref|https://perldoc.perl.org/perlreref.html>. If you don't know how to use regular expression but are interested in learning, you may consult L<perlretut|https://perldoc.perl.org/perlretut.html>. If you do not need or want ack to use regular expressions, please see the C<-Q>/C<--literal> option. Ack can also list files that would be searched, without actually searching them, to let you take advantage of ack's file-type filtering capabilities. =head1 FILE SELECTION If files are not specified for searching, either on the command line or piped in with the C<-x> option, I<ack> delves into subdirectories selecting files for searching. I<ack> is intelligent about the files it searches. It knows about certain file types, based on both the extension on the file and, in some cases, the contents of the file. These selections can be made with the B<--type> option. With no file selection, I<ack> searches through regular files that are not explicitly excluded by B<--ignore-dir> and B<--ignore-file> options, either present in F<ackrc> files or on the command line. The default options for I<ack> ignore certain files and directories. These include: =over 4 =item * Backup files: Files matching F<#*#> or ending with F<~>. =item * Coredumps: Files matching F<core.\d+> =item * Version control directories like F<.svn> and F<.git>. =back Run I<ack> with the C<--dump> option to see what settings are set. However, I<ack> always searches the files given on the command line, no matter what type. If you tell I<ack> to search in a coredump, it will search in a coredump. =head1 DIRECTORY SELECTION I<ack> descends through the directory tree of the starting directories specified. If no directories are specified, the current working directory is used. However, it will ignore the shadow directories used by many version control systems, and the build directories used by the Perl MakeMaker system. You may add or remove a directory from this list with the B<--[no]ignore-dir> option. The option may be repeated to add/remove multiple directories from the ignore list. For a complete list of directories that do not get searched, run C<ack --dump>. =head1 MATCHING IN A RANGE OF LINES The C<--range-start> and C<--range-end> options let you specify ranges of lines to search within each file. Say you had the following file, called F<testfile>: # This function calls print on "foo". sub foo { print 'foo'; } my $print = 1; sub bar { print 'bar'; } my $task = 'print'; Calling C<ack print> will give us five matches: $ ack print testfile # This function calls print on "foo". print 'foo'; my $print = 1; print 'bar'; my $task = 'print'; What if we only want to search for C<print> within the subroutines? We can specify ranges of lines that we want ack to search. The range starts with any line that matches the pattern C<^sub \w+>, and stops with any line that matches C<^}>. $ ack --range-start='^sub \w+' --range-end='^}' print testfile print 'foo'; print 'bar'; Note that ack searched two ranges of lines. The listing below shows which lines were in a range and which were out of the range. Out # This function calls print on "foo". In sub foo { In print 'foo'; In } Out my $print = 1; In sub bar { In print 'bar'; In } Out my $task = 'print'; You don't have to specify both C<--range-start> and C<--range-end>. IF C<--range-start> is omitted, then the range runs from the first line in the file unitl the first line that matches C<--range-end>. Similarly, if C<--range-end> is omitted, the range runs from the first line matching C<--range-start> to the end of the file. For example, if you wanted to search all HTML files up until the first instance of the C<< <body> >>, you could do ack foo --range-end='<body>' Or to search after Perl's `__DATA__` or `__END__` markers, you would do ack pattern --range-end='^__(END|DATA)__' It's possible for a range to start and stop on the same line. For example --range-start='<title>' --range-end='' would match this line as both the start and end of the range, making a one-line range. Page title Note that the patterns in C<--range-start> and C<--range-end> are not affected by options like C<-i>, C<-w> and C<-Q> that modify the behavior of the main pattern being matched. Again, ranges only affect where matches are looked for. Everything else in ack works the same way. Using C<-c> option with a range will give a count of all the matches that appear within those ranges. The C<-l> shows those files that have a match within a range, and the C<-L> option shows files that do not have a match within a range. The C<-v> option for negating a match works inside the range, too. To see lines that don't match "google" within the "" section of your HTML files, you could do: ack google -v --html --range-start=' will show all lines in the file, but only show matches for lines within the range. =head1 OPTIONS =over 4 =item B<--ackrc> Specifies an ackrc file to load after all others; see L. =item B<-A I>, B<--after-context=I> Print I lines of trailing context after matching lines. =item B<-B I>, B<--before-context=I> Print I lines of leading context before matching lines. =item B<--[no]break> Print a break between results from different files. On by default when used interactively. =item B<-C [I]>, B<--context[=I]> Print I lines (default 2) of context around matching lines. You can specify zero lines of context to override another context specified in an ackrc. =item B<-c>, B<--count> Suppress normal output; instead print a count of matching lines for each input file. If B<-l> is in effect, it will only show the number of lines for each file that has lines matching. Without B<-l>, some line counts may be zeroes. If combined with B<-h> (B<--no-filename>) ack outputs only one total count. =item B<--[no]color>, B<--[no]colour> B<--color> highlights the matching text. B<--nocolor> suppresses the color. This is on by default unless the output is redirected. On Windows, this option is off by default unless the L module is installed or the C environment variable is used. =item B<--color-filename=I> Sets the color to be used for filenames. =item B<--color-match=I> Sets the color to be used for matches. =item B<--color-colno=I> Sets the color to be used for column numbers. =item B<--color-lineno=I> Sets the color to be used for line numbers. =item B<--[no]column> Show the column number of the first match. This is helpful for editors that can place your cursor at a given position. =item B<--create-ackrc> Dumps the default ack options to standard output. This is useful for when you want to customize the defaults. =item B<--dump> Writes the list of options loaded and where they came from to standard output. Handy for debugging. =item B<--[no]env> B<--noenv> disables all environment processing. No F<.ackrc> is read and all environment variables are ignored. By default, F considers F<.ackrc> and settings in the environment. =item B<--flush> B<--flush> flushes output immediately. This is off by default unless ack is running interactively (when output goes to a pipe or file). =item B<-f> Only print the files that would be searched, without actually doing any searching. PATTERN must not be specified, or it will be taken as a path to search. =item B<--files-from=I> The list of files to be searched is specified in I. The list of files are separated by newlines. If I is C<->, the list is loaded from standard input. Note that the list of files is B filtered in any way. If you add C<--type=html> in addition to C<--files-from>, the C<--type> will be ignored. =item B<--[no]filter> Forces ack to act as if it were receiving input via a pipe. =item B<--[no]follow> Follow or don't follow symlinks, other than whatever starting files or directories were specified on the command line. This is off by default. =item B<-g I> Print searchable files where the relative path + filename matches I. Note that ack -g foo is exactly the same as ack -f | ack foo This means that just as ack will not search, for example, F<.jpg> files, C<-g> will not list F<.jpg> files either. ack is not intended to be a general-purpose file finder. Note also that if you have C<-i> in your .ackrc that the filenames to be matched will be case-insensitive as well. This option can be combined with B<--color> to make it easier to spot the match. =item B<--[no]group> B<--group> groups matches by file name. This is the default when used interactively. B<--nogroup> prints one result per line, like grep. This is the default when output is redirected. =item B<-H>, B<--with-filename> Print the filename for each match. This is the default unless searching a single explicitly specified file. =item B<-h>, B<--no-filename> Suppress the prefixing of filenames on output when multiple files are searched. =item B<--[no]heading> Print a filename heading above each file's results. This is the default when used interactively. =item B<--help> Print a short help statement. =item B<--help-types> Print all known types. =item B<--help-colors> Print a chart of various color combinations. =item B<--help-rgb-colors> Like B<--help-colors> but with more precise RGB colors. =item B<-i>, B<--ignore-case> Ignore case distinctions in PATTERN. Overrides B<--smart-case> and B<-I>. =item B<-I>, B<--no-ignore-case> Turns on case distinctions in PATTERN. Overrides B<--smart-case> and B<-i>. =item B<--ignore-ack-defaults> Tells ack to completely ignore the default definitions provided with ack. This is useful in combination with B<--create-ackrc> if you I want to customize ack. =item B<--[no]ignore-dir=I>, B<--[no]ignore-directory=I> Ignore directory (as CVS, .svn, etc are ignored). May be used multiple times to ignore multiple directories. For example, mason users may wish to include B<--ignore-dir=data>. The B<--noignore-dir> option allows users to search directories which would normally be ignored (perhaps to research the contents of F<.svn/props> directories). The I must always be a simple directory name. Nested directories like F are NOT supported. You would need to specify B<--ignore-dir=foo> and then no files from any foo directory are taken into account by ack unless given explicitly on the command line. =item B<--ignore-file=I> Ignore files matching I. The filters are specified identically to file type filters as seen in L. =item B<-k>, B<--known-types> Limit selected files to those with types that ack knows about. =item B<-l>, B<--files-with-matches> Only print the filenames of matching files, instead of the matching text. =item B<-L>, B<--files-without-matches> Only print the filenames of files that do I match. =item B<--match I> Specify the I explicitly. This is helpful if you don't want to put the regex as your first argument, e.g. when executing multiple searches over the same set of files. # search for foo and bar in given files ack file1 t/file* --match foo ack file1 t/file* --match bar =item B<-m=I>, B<--max-count=I> Print only I matches out of each file. If you want to stop ack after printing the first match of any kind, use the B<-1> options. =item B<--man> Print this manual page. =item B<-n>, B<--no-recurse> No descending into subdirectories. =item B<-o> Show only the part of each line matching PATTERN (turns off text highlighting). This is exactly the same as C<--output=$&>. =item B<--output=I> Output the evaluation of I for each line (turns off text highlighting). If PATTERN matches more than once then a line is output for each non-overlapping match. I may contain the strings "\n", "\r" and "\t", which will be expanded to their corresponding characters line feed, carriage return and tab, respectively. I may also contain the following Perl special variables: =over 4 =item C<$1> through C<$9> The subpattern from the corresponding set of capturing parentheses. If your pattern is C<(.+) and (.+)>, and the string is "this and that', then C<$1> is "this" and C<$2> is "that". =item C<$_> The contents of the line in the file. =item C<$.> The number of the line in the file. =item C<$&>, C<$`> and C<$'> C<$&> is the the string matched by the pattern, C<$`> is what precedes the match, and C<$'> is what follows it. If the pattern is C and the string is "lexicographic", then C<$&> is "graph", C<$`> is "lexico" and C<$'> is "ic". Use of these variables in your output will slow down the pattern matching. =item C<$+> The match made by the last parentheses that matched in the pattern. For example, if your pattern is C, then C<$+> will contain whichever set of parentheses matched. =item C<$f> C<$f> is available, in C<--output> only, to insert the filename. This is a stand-in for the discovered C<$filename> usage in old C<< ack2 --output >>, which is disallowed with C improved security. The intended usage is to provide the grep or compile-error syntax needed for editor/IDE go-to-line integration, e.g. C<--output=$f:$.:$_> or C<--output=$f\t$.\t$&> =back =item B<--pager=I>, B<--nopager> B<--pager> directs ack's output through I. This can also be specified via the C and C environment variables. Using --pager does not suppress grouping and coloring like piping output on the command-line does. B<--nopager> cancels any setting in F<~/.ackrc>, C or C. No output will be sent through a pager. =item B<--passthru> Prints all lines, whether or not they match the expression. Highlighting will still work, though, so it can be used to highlight matches while still seeing the entire file, as in: # Watch a log file, and highlight a certain IP address. $ tail -f ~/access.log | ack --passthru 123.45.67.89 =item B<--print0> Only works in conjunction with B<-f>, B<-g>, B<-l> or B<-c>, options that only list filenames. The filenames are output separated with a null byte instead of the usual newline. This is helpful when dealing with filenames that contain whitespace, e.g. # Remove all files of type HTML. ack -f --html --print0 | xargs -0 rm -f =item B<-p[N]>, B<--proximate[=N]> Groups together match lines that are within N lines of each other. This is useful for visually picking out matches that appear close to other matches. For example, if you got these results without the C<--proximate> option, 15: First match 18: Second match 19: Third match 37: Fourth match they would look like this with C<--proximate=1> 15: First match 18: Second match 19: Third match 37: Fourth match and this with C<--proximate=3>. 15: First match 18: Second match 19: Third match 37: Fourth match If N is omitted, N is set to 1. =item B<-P> Negates the effect of the B<--proximate> option. Shortcut for B<--proximate=0>. =item B<-Q>, B<--literal> Quote all metacharacters in PATTERN, it is treated as a literal. =item B<-r>, B<-R>, B<--recurse> Recurse into sub-directories. This is the default and just here for compatibility with grep. You can also use it for turning B<--no-recurse> off. =item B<--range-start=PATTERN>, B<--range-end=PATTERN> Specifies patterns that mark the start and end of a range. See L for details. =item B<-s> Suppress error messages about nonexistent or unreadable files. This is taken from fgrep. =item B<-S>, B<--[no]smart-case>, B<--no-smart-case> Ignore case in the search strings if PATTERN contains no uppercase characters. This is similar to C in the vim text editor. The options overrides B<-i> and B<-I>. B<-S> is a synonym for B<--smart-case>. B<-i> always overrides this option. =item B<--sort-files> Sorts the found files lexicographically. Use this if you want your file listings to be deterministic between runs of I. =item B<--show-types> Outputs the filetypes that ack associates with each file. Works with B<-f> and B<-g> options. =item B<-t TYPE>, B<--type=TYPE>, B<--TYPE> Specify the types of files to include in the search. TYPE is a filetype, like I or I. B<--type=perl> can also be specified as B<--perl>, although this is deprecated. Type inclusions can be repeated and are ORed together. See I for a list of valid types. =item B<-T TYPE>, B<--type=noTYPE>, B<--noTYPE> Specifies the type of files to exclude from the search. B<--type=noperl> can be done as B<--noperl>, although this is deprecated. If a file is of both type "foo" and "bar", specifying both B<--type=foo> and B<--type=nobar> will exclude the file, because an exclusion takes precedence over an inclusion. =item B<--type-add I:I:I> Files with the given ARGS applied to the given FILTER are recognized as being of (the existing) type TYPE. See also L. =item B<--type-set I:I:I> Files with the given ARGS applied to the given FILTER are recognized as being of type TYPE. This replaces an existing definition for type TYPE. See also L. =item B<--type-del I> The filters associated with TYPE are removed from Ack, and are no longer considered for searches. =item B<--[no]underline> Turns on underlining of matches, where "underlining" is printing a line of carets under the match. $ ack -u foo peanuts.txt 17: Come kick the football you fool ^^^ ^^^ 623: Price per square foot ^^^ This is useful if you're dumping the results of an ack run into a text file or printer that doesn't support ANSI color codes. The setting of underline does not affect highlighting of matches. =item B<-v>, B<--invert-match> Invert match: select non-matching lines. =item B<--version> Display version and copyright information. =item B<-w>, B<--word-regexp> Force PATTERN to match only whole words. =item B<-x> An abbreviation for B<--files-from=->. The list of files to search are read from standard input, with one line per file. Note that the list of files is B filtered in any way. If you add C<--type=html> in addition to C<-x>, the C<--type> will be ignored. =item B<-1> Stops after reporting first match of any kind. This is different from B<--max-count=1> or B<-m1>, where only one match per file is shown. Also, B<-1> works with B<-f> and B<-g>, where B<-m> does not. =item B<--thpppt> Display the all-important Bill The Cat logo. Note that the exact spelling of B<--thpppppt> is not important. It's checked against a regular expression. =item B<--bar> Check with the admiral for traps. =item B<--cathy> Chocolate, Chocolate, Chocolate! =back =head1 THE .ackrc FILE The F<.ackrc> file contains command-line options that are prepended to the command line before processing. Multiple options may live on multiple lines. Lines beginning with a # are ignored. A F<.ackrc> might look like this: # Always sort the files --sort-files # Always color, even if piping to another program --color # Use "less -r" as my pager --pager=less -r Note that arguments with spaces in them do not need to be quoted, as they are not interpreted by the shell. Basically, each I in the F<.ackrc> file is interpreted as one element of C<@ARGV>. F looks in several locations for F<.ackrc> files; the searching process is detailed in L. These files are not considered if B<--noenv> is specified on the command line. =head1 Defining your own types ack allows you to define your own types in addition to the predefined types. This is done with command line options that are best put into an F<.ackrc> file - then you do not have to define your types over and over again. In the following examples the options will always be shown on one command line so that they can be easily copy & pasted. File types can be specified both with the the I<--type=xxx> option, or the file type as an option itself. For example, if you create a filetype of "cobol", you can specify I<--type=cobol> or simply I<--cobol>. File types must be at least two characters long. This is why the C language is I<--cc> and the R language is I<--rr>. I searches for foo in all perl files. I tells you, that perl files are files ending in .pl, .pm, .pod or .t. So what if you would like to include .xs files as well when searching for --perl files? I does this for you. B<--type-add> appends additional extensions to an existing type. If you want to define a new type, or completely redefine an existing type, then use B<--type-set>. I defines the type I to include files with the extensions .e or .eiffel. So to search for all eiffel files containing the word Bertrand use I. As usual, you can also write B<--type=eiffel> instead of B<--eiffel>. Negation also works, so B<--noeiffel> excludes all eiffel files from a search. Redefining also works: I and I<.xs> files no longer belong to the type I. When defining your own types in the F<.ackrc> file you have to use the following: --type-set=eiffel:ext:e,eiffel or writing on separate lines --type-set eiffel:ext:e,eiffel The following does B work in the F<.ackrc> file: --type-set eiffel:ext:e,eiffel In order to see all currently defined types, use I<--help-types>, e.g. I In addition to filtering based on extension, ack offers additional filter types. The generic syntax is I<--type-set TYPE:FILTER:ARGS>; I depends on the value of I. =over 4 =item is:I I filters match the target filename exactly. It takes exactly one argument, which is the name of the file to match. Example: --type-set make:is:Makefile =item ext:I[,I[,...]] I filters match the extension of the target file against a list of extensions. No leading dot is needed for the extensions. Example: --type-set perl:ext:pl,pm,t =item match:I I filters match the target filename against a regular expression. The regular expression is made case-insensitive for the search. Example: --type-set make:match:/(gnu)?makefile/ =item firstlinematch:I I matches the first line of the target file against a regular expression. Like I, the regular expression is made case insensitive. Example: --type-add perl:firstlinematch:/perl/ =back =head1 ACK COLORS ack allows customization of the colors it uses when presenting matches onscreen. It uses the colors available in Perl's L module, which provides the following listed values. Note that case does not matter when using these values. There are four different colors ack uses: Aspect Option Env. variable Default -------- ----------------- ------------------ --------------- filename --color-filename ACK_COLOR_FILENAME black on_yellow match --color-match ACK_COLOR_MATCH bold green line no. --color-lineno ACK COLOR_LINENO bold yellow column no. --color-colno ACK COLOR_COLNO bold yellow The column number column is only used if the column number is shown because of the --column option. Colors may be specified by command-line option, such as C, or by setting an environment variable, such as C. Options for colors can be set in your ACKRC file (See "THE .ackrc FILE"). ack can understand the following colors for the foreground: black red green yellow blue magenta cyan white The optional background color is specified by prepending "on_" to one of the foreground colors: on_black on_red on_green on_yellow on_blue on_magenta on_cyan on_white Each of the foreground colors can be modified with the following attributes, which may or may not be supported by your terminal: bold faint italic underline blink reverse concealed Any combinations of modifiers can be added to the foreground color. If your terminal supports it, and you enjoy visual punishment, you can specify: ack --color-filename="blink italic underline bold red on_yellow" For charts of the colors and what they look like, run C and C. If the eight standard colors, in their bold, faint and unmodified states, aren't enough for you to choose from, you can also specify colors by their RGB values. They are specified as "rgbXYZ" where X, Y, and Z are values between 0 and 5 giving the intensity of red, green and blue, respectively. Therefore, "rgb500" is pure red, "rgb505" is purple, and so on. Background colors can be specified with the "on_" prefix prepended on an RGB color, so that "on_rgb505" would be a purple background. The modifier attributes of blink, italic, underscore and so on may or may not work on the RGB colors. For a chart of the 216 possible RGB colors, run C. =head1 ENVIRONMENT VARIABLES For commonly-used ack options, environment variables can make life much easier. These variables are ignored if B<--noenv> is specified on the command line. =over 4 =item ACKRC Specifies the location of the user's F<.ackrc> file. If this file doesn't exist, F looks in the default location. =item ACK_COLOR_COLNO Color specification for the column number in ack's output. By default, the column number is not shown. You have to enable it with the B<--column> option. See the section "ack Colors" above. =item ACK_COLOR_FILENAME Color specification for the filename in ack's output. See the section "ack Colors" above. =item ACK_COLOR_LINENO Color specification for the line number in ack's output. See the section "ack Colors" above. =item ACK_COLOR_MATCH Color specification for the matched text in ack's output. See the section "ack Colors" above. =item ACK_PAGER Specifies a pager program, such as C, C or C, to which ack will send its output. Using C does not suppress grouping and coloring like piping output on the command-line does, except that on Windows ack will assume that C does not support color. C overrides C if both are specified. =item ACK_PAGER_COLOR Specifies a pager program that understands ANSI color sequences. Using C does not suppress grouping and coloring like piping output on the command-line does. If you are not on Windows, you never need to use C. =back =head1 ACK & OTHER TOOLS =head2 Simple vim integration F integrates easily with the Vim text editor. Set this in your F<.vimrc> to use F instead of F: set grepprg=ack\ -k That example uses C<-k> to search through only files of the types ack knows about, but you may use other default flags. Now you can search with F and easily step through the results in Vim: :grep Dumper perllib =head2 Editor integration Many users have integrated ack into their preferred text editors. For details and links, see L. =head2 Shell and Return Code For greater compatibility with I, I in normal use returns shell return or exit code of 0 only if something is found and 1 if no match is found. (Shell exit code 1 is C<$?=256> in perl with C or backticks.) The I code 2 for errors is not used. If C<-f> or C<-g> are specified, then 0 is returned if at least one file is found. If no files are found, then 1 is returned. =cut =head1 DEBUGGING ACK PROBLEMS If ack gives you output you're not expecting, start with a few simple steps. =head2 Try it with B<--noenv> Your environment variables and F<.ackrc> may be doing things you're not expecting, or forgotten you specified. Use B<--noenv> to ignore your environment and F<.ackrc>. =head2 Use B<-f> to see what files have been selected for searching Ack's B<-f> was originally added as a debugging tool. If ack is not finding matches you think it should find, run F to see what files have been selected. You can also add the C<--show-types> options to show the type of each file selected. =head2 Use B<--dump> This lists the ackrc files that are loaded and the options loaded from them. You may be loading an F<.ackrc> file that you didn't know you were loading. =head1 ACKRC LOCATION SEMANTICS Ack can load its configuration from many sources. The following list specifies the sources Ack looks for configuration files; each one that is found is loaded in the order specified here, and each one overrides options set in any of the sources preceding it. (For example, if I set --sort-files in my user ackrc, and --nosort-files on the command line, the command line takes precedence) =over 4 =item * Defaults are loaded from App::Ack::ConfigDefaults. This can be omitted using C<--ignore-ack-defaults>. =item * Global ackrc Options are then loaded from the global ackrc. This is located at C on Unix-like systems. Under Windows XP and earlier, the global ackrc is at C Under Windows Vista/7, the global ackrc is at C The C<--noenv> option prevents all ackrc files from being loaded. =item * User ackrc Options are then loaded from the user's ackrc. This is located at C<$HOME/.ackrc> on Unix-like systems. Under Windows XP and earlier, the user's ackrc is at C. Under Windows Vista/7, the user's ackrc is at C. If you want to load a different user-level ackrc, it may be specified with the C<$ACKRC> environment variable. The C<--noenv> option prevents all ackrc files from being loaded. =item * Project ackrc Options are then loaded from the project ackrc. The project ackrc is the first ackrc file with the name C<.ackrc> or C<_ackrc>, first searching in the current directory, then the parent directory, then the grandparent directory, etc. This can be omitted using C<--noenv>. =item * --ackrc The C<--ackrc> option may be included on the command line to specify an ackrc file that can override all others. It is consulted even if C<--noenv> is present. =item * Command line Options are then loaded from the command line. =back =head1 BUGS & ENHANCEMENTS ack is based at GitHub at L Please report any bugs or feature requests to the issues list at Github: L. Please include the operating system that you're using; the output of the command C; and any customizations in your F<.ackrc> you may have. To suggest enhancements, please submit an issue at L. Also read the F file in the ack code repository. Also, feel free to discuss your issues on the ack mailing list at L. =head1 SUPPORT Support for and information about F can be found at: =over 4 =item * The ack homepage L =item * Source repository L =item * The ack issues list at Github L =item * The ack announcements mailing list L =item * The ack users' mailing list L =item * The ack development mailing list L =back =head1 COMMUNITY There are ack mailing lists and a Slack channel for ack. See L for details. =head1 FAQ This is the Frequently Asked Questions list for ack. =head2 Can I stop using grep now? Many people find I to be better than I as an everyday tool 99% of the time, but don't throw I away, because there are times you'll still need it. For example, you might be looking through huge log files and not using regular expressions. In that case, I will probably perform better. =head2 Why isn't ack finding a match in (some file)? First, take a look and see if ack is even looking at the file. ack is intelligent in what files it will search and which ones it won't, but sometimes that can be surprising. Use the C<-f> switch, with no regex, to see a list of files that ack will search for you. If your file doesn't show up in the list of files that C shows, then ack never looks in it. =head2 Wouldn't it be great if F did search & replace? No, ack will always be read-only. Perl has a perfectly good way to do search & replace in files, using the C<-i>, C<-p> and C<-n> switches. You can certainly use ack to select your files to update. For example, to change all "foo" to "bar" in all PHP files, you can do this from the Unix shell: $ perl -i -p -e's/foo/bar/g' $(ack -f --php) =head2 Can I make ack recognize F<.xyz> files? Yes! Please see L in the ack manual. =head2 Will you make ack recognize F<.xyz> files by default? We might, depending on how widely-used the file format is. Submit an issue at in the GitHub issue queue at L. Explain what the file format is, where we can find out more about it, and what you have been using in your F<.ackrc> to support it. Please do not bother creating a pull request. The code for filetypes is trivial compared to the rest of the process we go through. =head2 Why is it called ack if it's called ack-grep? The name of the program is "ack". Some packagers have called it "ack-grep" when creating packages because there's already a package out there called "ack" that has nothing to do with this ack. I suggest you make a symlink named F that points to F because one of the crucial benefits of ack is having a name that's so short and simple to type. To do that, run this with F or as root: ln -s /usr/bin/ack-grep /usr/bin/ack Alternatively, you could use a shell alias: # bash/zsh alias ack=ack-grep # csh alias ack ack-grep =head2 What does F mean? Nothing. I wanted a name that was easy to type and that you could pronounce as a single syllable. =head2 Can I do multi-line regexes? No, ack does not support regexes that match multiple lines. Doing so would require reading in the entire file at a time. If you want to see lines near your match, use the C<--A>, C<--B> and C<--C> switches for displaying context. =head2 Why is ack telling me I have an invalid option when searching for C<+foo>? ack treats command line options beginning with C<+> or C<-> as options; if you would like to search for these, you may prefix your search term with C<--> or use the C<--match> option. (However, don't forget that C<+> is a regular expression metacharacter!) =head2 Why does C<"ack '.{40000,}'"> fail? Isn't that a valid regex? The Perl language limits the repetition quantifier to 32K. You can search for C<.{32767}> but not C<.{32768}>. =head2 Ack does "X" and shouldn't, should it? We try to remain as close to grep's behavior as possible, so when in doubt, see what grep does! If there's a mismatch in functionality there, please submit an issue to GitHub, and/or bring it up on the ack-users mailing list. =cut =head1 ACKNOWLEDGEMENTS How appropriate to have Inowledgements! Thanks to everyone who has contributed to ack in any way, including Dan Book, Tomasz Konojacki, Salomon Smeke, M. Scott Ford, Anders Eriksson, H.Merijn Brand, Duke Leto, Gerhard Poul, Ethan Mallove, Marek Kubica, Ray Donnelly, Nikolaj Schumacher, Ed Avis, Nick Morrott, Austin Chamberlin, Varadinsky, SEbastien FeugEre, Jakub Wilk, Pete Houston, Stephen Thirlwall, Jonah Bishop, Chris Rebert, Denis Howe, RaEl GundEn, James McCoy, Daniel Perrett, Steven Lee, Jonathan Perret, Fraser Tweedale, RaEl GundEn, Steffen Jaeckel, Stephan Hohe, Michael Beijen, Alexandr Ciornii, Christian Walde, Charles Lee, Joe McMahon, John Warwick, David Steinbrunner, Kara Martens, Volodymyr Medvid, Ron Savage, Konrad Borowski, Dale Sedivic, Michael McClimon, Andrew Black, Ralph Bodenner, Shaun Patterson, Ryan Olson, Shlomi Fish, Karen Etheridge, Olivier Mengue, Matthew Wild, Scott Kyle, Nick Hooey, Bo Borgerson, Mark Szymanski, Marq Schneider, Packy Anderson, JR Boyens, Dan Sully, Ryan Niebur, Kent Fredric, Mike Morearty, Ingmar Vanhassel, Eric Van Dewoestine, Sitaram Chamarty, Adam James, Richard Carlsson, Pedro Melo, AJ Schuster, Phil Jackson, Michael Schwern, Jan Dubois, Christopher J. Madsen, Matthew Wickline, David Dyck, Jason Porritt, Jjgod Jiang, Thomas Klausner, Uri Guttman, Peter Lewis, Kevin Riggle, Ori Avtalion, Torsten Blix, Nigel Metheringham, GEbor SzabE, Tod Hagan, Michael Hendricks, Evar ArnfjErE Bjarmason, Piers Cawley, Stephen Steneker, Elias Lutfallah, Mark Leighton Fisher, Matt Diephouse, Christian Jaeger, Bill Sully, Bill Ricker, David Golden, Nilson Santos F. Jr, Elliot Shank, Merijn Broeren, Uwe Voelker, Rick Scott, Ask BjErn Hansen, Jerry Gay, Will Coleda, Mike O'Regan, Slaven ReziE<0x107>, Mark Stosberg, David Alan Pisoni, Adriano Ferreira, James Keenan, Leland Johnson, Ricardo Signes, Pete Krawczyk and Rob Hoelz. =head1 AUTHOR Andy Lester, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2005-2021 Andy Lester. This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License v2.0. See https://www.perlfoundation.org/artistic-license-20.html or the LICENSE.md file that comes with the ack distribution. =cut 1; ack-v3.5.0/squash0000755000175100017510000000502214023027176012350 0ustar andyandy#!perl =pod Squashes together the parts of ack into the single ack-standalone file. The arguments to squash are either filenames from the ack distro like Ack.pm, or module names like File::Next. For modules, squash loads them and then pushes them into ack-standalone. POD gets stripped from all modules. =cut use warnings; use strict; use File::Next; # Make clear that ack is not supposed to be edited. my $NO_EDIT_COMMENT = <<'EOCOMMENT'; # # This file, ack, is generated code. # Please DO NOT EDIT or send patches for it. # # Please take a look at the source from # https://github.com/beyondgrep/ack3 # and submit patches against the individual files # that build ack. # EOCOMMENT my $debug_mode = grep { $_ eq '--debug' } @ARGV; @ARGV = grep { $_ ne '--debug' } @ARGV; my $code = <<"PERL"; #!/usr/bin/env perl $NO_EDIT_COMMENT \$App::Ack::STANDALONE = 1; PERL for my $arg ( @ARGV ) { my $filename = $arg; if ( $arg =~ /::/ ) { my $key = "$arg.pm"; $key =~ s{::}{/}g; $filename = $INC{$key} or die "Can't find the file for $arg"; } warn "Reading $filename\n"; open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; my $was_in_pod = 0; my $in_pod = 0; $code .= "#line 1 '$filename'\n" if $debug_mode && $filename ne 'ack'; while ( <$fh> ) { next if /^use (?:File::Next|App::Ack)/; s/^use parent (.+)/BEGIN {\n our \@ISA = $1\n}/; if ( $was_in_pod && !$in_pod ) { $was_in_pod = 0; if ($debug_mode) { $code .= "#line $. '$filename'\n"; } } # See if we're in module POD blocks. if ( $filename ne 'ack' ) { $was_in_pod = $in_pod; if ( /^=(\w+)/ ) { $in_pod = ($1 ne 'cut'); next; } elsif ( $in_pod ) { next; } } # Replace the shebang line and append 'no edit' comment if ( s{^#!.+}{package main;} ) { # Skip the shebang line and replace it with package statement. } # Remove Perl::Critic comments. # I'd like to remove all comments, but this is a start s{\s*##.+critic.*}{}; $code .= $_; } close $fh; } # We only use two of the four constructors in File::Next, so delete the other two. for my $unused_func ( qw( dirs everything ) ) { $code =~ s/^sub $unused_func\b.*?^}//sm or die qq{Unable to find the sub "$unused_func" to remove from ack-standalone}; } print $code; exit 0; ack-v3.5.0/xt/0000755000175100017510000000000014023040526011544 5ustar andyandyack-v3.5.0/xt/pod.t0000644000175100017510000000013414023027176012517 0ustar andyandy#!perl use warnings; use strict; use Test::More; use Test::Pod 1.14; all_pod_files_ok(); ack-v3.5.0/xt/coresubs.t0000644000175100017510000000310014023027176013556 0ustar andyandy#!perl # Checks that we are not using core C or C except in very specific places. # Same with C and C. # Ignore the App::Ack::Docs modules since they're nothing but text. ## no critic ( Bangs::ProhibitDebuggingModules ) use warnings; use strict; use Test::More tests => 4; use lib 't'; use Util; prep_environment(); my $ack_pm = quotemeta( reslash( 'blib/lib/App/Ack.pm' ) ); my @exclusions = qw( --ignore-dir=dev --ignore-file=is:ack-standalone ); for my $word ( qw( warn die ) ) { subtest "Finding $word" => sub { plan tests => 4; my @args = ( '(? or C. Use C and C. my $util_pm = quotemeta( reslash( 't/Util.pm' ) ); for my $word ( qw( chdir mkdir ) ) { subtest "Finding $word" => sub { plan tests => 3; my @args = ( '-w', '--ignore-file=is:coresubs.t', '--ignore-file=is:Dockerfile', '--ignore-dir=garage', @exclusions, $word ); my @results = run_ack( @args ); is( scalar @results, 1, 'Exactly one hit...' ) or do { require Data::Dumper; warn Data::Dumper::Dumper( \@results ) }; like( $results[0], qr/^$util_pm.+CORE::$word/, '... and it is in the function in Util.pm that wraps the core call' ); }; } exit 0; ack-v3.5.0/xt/coding-standards.t0000644000175100017510000000277514023027176015176 0ustar andyandy#!perl use warnings; use strict; use lib 't'; use File::Next; use Util; use Test::More; # Get all the ack component files. my @files = ( 'ack' ); my $libs = File::Next::files( { descend_filter => sub { !/\Q.git/ }, file_filter => sub { /\.pm$/ } }, 'lib' ); while ( my $file = $libs->() ) { push @files, $file; } @files == 20 or die 'I should have exactly 20 modules + ack'; # Get all the test files. for my $spec ( 't/*.t', 'xt/*.t' ) { my @these_files = glob( $spec ) or die "Couldn't find any $spec"; push( @files, @these_files ); } @files = grep { !/lowercase.t/ } @files; # lowercase.t has hi-bit and it's OK. plan tests => scalar @files; for my $file ( @files ) { subtest $file => sub { plan tests => 3; my @lines = read_file( $file ); my $text = join( '', @lines ); chomp @lines; my $ok = 1; my $lineno = 0; for my $line ( @lines ) { ++$lineno; if ( $line =~ /[^ -~]/ ) { my $col = $-[0] + 1; diag( "$file has hi-bit characters at $lineno:$col" ); $ok = 0; } if ( $line =~ /\s+$/ ) { diag( "$file has trailing whitespace on line $lineno" ); $ok = 0; } } ok( $ok, "$file: No hi-bit characters found and no trailing whitespace" ); ok( $lines[-1] ne '', "$file: Doesn't end with an empty line" ); is( index($text, "\t"), -1, "$file should have no embedded tabs" ); } } ack-v3.5.0/xt/man.t0000644000175100017510000000651614023027176012522 0ustar andyandy#!perl ## no critic ( Bangs::ProhibitDebuggingModules ) use strict; use warnings; use lib 't'; use Test::More; use Util; sub strip_special_chars { my ( $s ) = @_; $s =~ s/.[\b]//g; $s =~ s/\e\[?.*?[\@-~]//g; return $s; } { my $man_options; sub _populate_man_options { my ( $man_output, $man_stderr ) = run_ack_with_stderr( '--man' ); if ( !@{$man_stderr} ) { pass( 'Nothing in stderr' ); } elsif ( @{$man_stderr} > 1 ) { fail( 'I have more than two lines in stderr' ); diag explain $man_stderr; } else { # Sometimes "standard input" is in single quotes, and sometimes it's not. like( $man_stderr->[0], qr/stty: '?standard input'?: Inappropriate ioctl for device/, 'The one warning is one we can ignore' ); } my $in_options_section; my @option_lines; foreach my $line ( @{$man_output} ) { $line = strip_special_chars($line); if ( $line =~ /^OPTIONS/ ) { $in_options_section = 1; } elsif ( $in_options_section ) { if ( $line =~ /^\S/ ) { $in_options_section = 0; last; } else { push @option_lines, $line; } } } my $min_indent; foreach my $line ( @option_lines ) { if ( my ( $indent ) = $line =~ /^(\s+)/ ) { $indent =~ s/\t/ /; $indent = length($indent); if ( !defined($min_indent) || $indent < $min_indent ) { $min_indent = $indent; } } } $man_options = []; foreach my $line ( @option_lines ) { if ( $line =~ /^(\s+)/ ) { my $indent_str = $1; $indent_str =~ s/\t/ /; my $indent = length($indent_str); next unless $indent == $min_indent; while ( $line =~ /(-[^\s=,]+)/g ) { my $option = $1; chop $option if $option =~ /\[$/; if ( $option =~ s/^--\[no\]/--/ ) { my $negated_option = $option; substr $negated_option, 2, 0, 'no'; push @{$man_options}, $negated_option; } push @{$man_options}, $option; } } } return; } sub get_man_options { _populate_man_options() unless $man_options; return @{ $man_options }; } } sub check_for_option_in_man_output { local $Test::Builder::Level = $Test::Builder::Level + 1; my $expected_option = shift; my @options = get_man_options(); foreach my $option ( @options ) { if ( $option eq $expected_option ) { return pass( "Found $expected_option in --man output" ); } } require Data::Dumper; diag Data::Dumper::Dumper( 'Returned options' => \@options ); return fail( "Option '$expected_option' not found in --man output" ); } my @options = get_expected_options(); plan tests => scalar(@options) + 1; prep_environment(); foreach my $option ( @options ) { check_for_option_in_man_output( $option ); } exit 0; ack-v3.5.0/LICENSE.md0000644000175100017510000002166314023027176012533 0ustar andyandyack is released under the [Artistic License 2.0][1]. [1]: https://www.perlfoundation.org/artistic-license-20.html Artistic License 2.0 ==================== Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble -------- This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions ----------- "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution -------------------------------------------------------- (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version ------------------------------------------------------ (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source ---------------------------------------------------------------------------------------------- (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package ---------------------------------- (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version -------------------------------------------------------- (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions ------------------ (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ack-v3.5.0/Makefile.PL0000644000175100017510000001136614023040515013070 0ustar andyandypackage main; require 5.010001; use strict; use warnings; use ExtUtils::MakeMaker; print "Running Perl $^V at $^X\n"; my $debug_mode = (grep { $_ eq '--debug' } @ARGV) ? '--debug' : ''; my %parms = ( NAME => 'ack', AUTHOR => 'Andy Lester ', ABSTRACT => 'A grep-like program for searching source code', VERSION_FROM => 'lib/App/Ack.pm', LICENSE => 'artistic_2', MIN_PERL_VERSION => 5.010001, META_MERGE => { resources => { homepage => 'https://beyondgrep.com/', bugtracker => 'https://github.com/beyondgrep/ack3', license => 'https://www.perlfoundation.org/artistic-license-20.html', repository => 'git://github.com/beyondgrep/ack3.git', MailingList => 'https://groups.google.com/group/ack-users', }, }, EXE_FILES => [ 'ack' ], PREREQ_PM => { 'Cwd' => '3.00', 'File::Basename' => '1.00015', 'File::Next' => '1.18', 'File::Spec' => '3.00', 'File::Temp' => '0.19', # For newdir() 'Getopt::Long' => '2.38', 'if' => 0, 'List::Util' => 0, 'parent' => 0, 'Pod::Perldoc' => '3.20', # Starting with 3.20, default output is Pod::Perldoc::ToTerm instead of ::ToMan 'Pod::Text' => 0, # Used to render pod by Pod::Usage. 'Pod::Usage' => '1.26', 'Scalar::Util' => 0, 'Term::ANSIColor' => '1.10', 'Test::Harness' => '2.50', # Something reasonably newish 'Test::More' => '0.98', # For subtest() 'Text::ParseWords' => '3.1', 'version' => 0, ( $^O eq 'MSWin32' ? ('Win32::ShellQuote' => '0.002001') : () ), }, MAN3PODS => {}, # no need for man pages for any of the .pm files dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'ack-3* nytprof* stderr.log stdout.log completion.*' }, ); WriteMakefile( %parms ); package MY; # Suppress EU::MM test rule. sub MY::test { return ''; } sub MY::postamble { my $postamble = sprintf(<<'MAKE_FRAG', $debug_mode); ACK = ack CODE_PM = \ lib/App/Ack.pm \ \ lib/App/Ack/ConfigDefault.pm \ lib/App/Ack/ConfigFinder.pm \ lib/App/Ack/ConfigLoader.pm \ lib/App/Ack/File.pm \ lib/App/Ack/Files.pm \ lib/App/Ack/Filter.pm \ \ lib/App/Ack/Filter/Collection.pm \ lib/App/Ack/Filter/Default.pm \ lib/App/Ack/Filter/Extension.pm \ lib/App/Ack/Filter/ExtensionGroup.pm \ lib/App/Ack/Filter/FirstLineMatch.pm \ lib/App/Ack/Filter/Inverse.pm \ lib/App/Ack/Filter/Is.pm \ lib/App/Ack/Filter/IsGroup.pm \ lib/App/Ack/Filter/IsPath.pm \ lib/App/Ack/Filter/IsPathGroup.pm \ lib/App/Ack/Filter/Match.pm \ lib/App/Ack/Filter/MatchGroup.pm \ TEST_VERBOSE=0 TEST_UTILS=t/*.pm TEST_FILES=t/*.t TEST_XT_FILES=xt/*.t .PHONY: tags critic tags: ctags -f tags --recurse --totals \ --exclude=blib \ --exclude=.git \ --exclude='*~' \ --exclude=ack-standalone \ --exclude=garage/* \ --exclude=ack-v3*/* \ --languages=Perl --langmap=Perl:+.t \ # Don't run critic on docs. critic: perlcritic -1 -q -profile perlcriticrc $(ACK) $(CODE_PM) $(TEST_UTILS) $(TEST_FILES) $(TEST_XT_FILES) ack-standalone : $(ACK) $(CODE_PM) squash Makefile $(PERL) squash $(ACK) $(CODE_PM) File::Next %s > ack-standalone $(FIXIN) ack-standalone -$(NOECHO) $(CHMOD) $(PERM_RWX) ack-standalone $(PERL) -c ack-standalone bininst : $(ACK) $(CP) $(ACK) ~/bin/ack3 $(CP) ackrc ~/.ack3rc test: test_classic test_standalone fulltest: test_classic test_standalone test_xt test_classic: all $(FULLPERLRUN) t/runtests.pl 0 $(TEST_VERBOSE) "$(INST_LIB)" "$(INST_ARCHLIB)" $(TEST_FILES) test_standalone: all ack-standalone $(FULLPERLRUN) t/runtests.pl 1 $(TEST_VERBOSE) "$(INST_LIB)" "$(INST_ARCHLIB)" $(TEST_FILES) test_xt: all $(FULLPERLRUN) t/runtests.pl 0 $(TEST_VERBOSE) "$(INST_LIB)" "$(INST_ARCHLIB)" $(TEST_XT_FILES) PROF_ARGS = -Mblib blib/script/ack foo ~/parrot nytprof: all $(PERL) -d:NYTProf $(PROF_ARGS) >> /dev/null 2>&1 nytprofhtml TIMER_ARGS=foo ~/parrot > /dev/null time-ack196: time $(PERL) ./garage/ack196 --noenv $(TIMER_ARGS) time-head: ack-standalone time $(PERL) ./ack-standalone --noenv $(TIMER_ARGS) timings: ack-standalone ./dev/timings.pl ~/parrot timings-beta: ack-standalone ./dev/timings.pl ~/parrot --ack=2.999_0{1,2,3,4,5,6} completion.bash: pm_to_blib ./dev/generate-completion-scripts.pl completion.bash completion.zsh: pm_to_blib ./dev/generate-completion-scripts.pl completion.zsh MAKE_FRAG return $postamble; } 1; ack-v3.5.0/MANIFEST0000644000175100017510000001200214023040526012235 0ustar andyandyChanges LICENSE.md MANIFEST README.md Makefile.PL ack lib/App/Ack.pm lib/App/Ack/ConfigDefault.pm lib/App/Ack/ConfigFinder.pm lib/App/Ack/ConfigLoader.pm lib/App/Ack/File.pm lib/App/Ack/Files.pm lib/App/Ack/Filter.pm lib/App/Ack/Filter/Collection.pm lib/App/Ack/Filter/Default.pm lib/App/Ack/Filter/Extension.pm lib/App/Ack/Filter/ExtensionGroup.pm lib/App/Ack/Filter/FirstLineMatch.pm lib/App/Ack/Filter/Inverse.pm lib/App/Ack/Filter/Is.pm lib/App/Ack/Filter/IsGroup.pm lib/App/Ack/Filter/IsPath.pm lib/App/Ack/Filter/IsPathGroup.pm lib/App/Ack/Filter/Match.pm lib/App/Ack/Filter/MatchGroup.pm squash t/Barfly.pm t/Util.pm t/test-pager t/00-load.t t/ack-1.t t/ack-color.t t/ack-column.t t/ack-c.t t/ack-files-from.t t/ack-f.t t/ack-group.t t/ack-g.t t/ack-help.t t/ack-help-types.t t/ack-h.t t/ack-ignore-dir.t t/ack-ignore-file.t t/ack-i.t t/ack-i.barfly t/ack-k.t t/ack-l.t t/ack-match.t t/ack-m.t t/ack-man.t t/ack-n.t t/ack-o.t t/ack-output.t t/ack-pager.t t/ack-passthru.t t/ack-print0.t t/ack-proximate.t t/ack-Q.t t/ack-show-types.t t/ack-s.t t/ack-type-del.t t/ack-type.t t/ack-underline.barfly t/ack-underline.t t/ack-v.t t/ack-w.t t/ack-w.barfly t/ack-x.t t/anchored.t t/bad-ackrc-opt.t t/basic.t t/command-line-files.t t/config-backwards-compat.t t/context.t t/context-with-newlines.t t/double-hyphen.t t/empty-lines.t t/exit-code.t t/file-permission.t t/filetype-detection.t t/filetypes.t t/forbidden-options.t t/from-stdin.t t/highlighting.t t/illegal-regex.t t/incomplete-last-line.t t/interactive.t t/invalid-ackrc.t t/invalid-options.t t/inverted-file-filter.t t/line-endings.t t/longopts.t t/multiple-captures.t t/mutex-options.t t/named-pipes.t t/needs-line-scan.t t/noackrc.t t/prescan-line-boundaries.t t/process-substitution.t t/runtests.pl t/trailing-whitespace.t t/zero.t t/internals/FilterTest.pm t/internals/ack-create-ackrc.t t/internals/ack-dump.t t/internals/ack-version.t t/internals/config-finder.t t/internals/config-loader.t t/internals/default-filter.t t/internals/ext-filter.t t/internals/file-iterator.t t/internals/filter.t t/internals/firstlinematch-filter.t t/internals/is-filter.t t/internals/lowercase.t t/internals/match-filter.t t/internals/noenv.t t/etc/buttonhook.xml.xxx t/etc/shebang.empty.xxx t/etc/shebang.foobar.xxx t/etc/shebang.php.xxx t/etc/shebang.pl.xxx t/etc/shebang.py.xxx t/etc/shebang.rb.xxx t/etc/shebang.sh.xxx t/home/.ackrc t/range/rangefile.pm t/range/america-the-beautiful.html t/range/anchors-aweigh.html t/range/johnny-rebeck.txt t/range/stars-and-stripes-forever.html t/swamp/__pycache__/notes.pl t/swamp/#emacs-workfile.pl# t/swamp/0 t/swamp/CMakeLists.txt t/swamp/Makefile t/swamp/Makefile.PL t/swamp/MasterPage.master t/swamp/Rakefile t/swamp/Sample.ascx t/swamp/Sample.asmx t/swamp/blib/ignore.pm t/swamp/blib/ignore.pod t/swamp/c-header.h t/swamp/c-source.c t/swamp/constitution-100k.pl t/swamp/crystallography-weenies.f t/swamp/example.R t/swamp/favicon.ico t/swamp/file.bar t/swamp/file.foo t/swamp/fresh.css t/swamp/fresh.css.min t/swamp/fresh.min.css t/swamp/groceries/CVS/fruit t/swamp/groceries/CVS/junk t/swamp/groceries/CVS/meat t/swamp/groceries/RCS/fruit t/swamp/groceries/RCS/junk t/swamp/groceries/RCS/meat t/swamp/groceries/another_subdir/CVS/fruit t/swamp/groceries/another_subdir/CVS/junk t/swamp/groceries/another_subdir/CVS/meat t/swamp/groceries/another_subdir/RCS/fruit t/swamp/groceries/another_subdir/RCS/junk t/swamp/groceries/another_subdir/RCS/meat t/swamp/groceries/another_subdir/fruit t/swamp/groceries/another_subdir/junk t/swamp/groceries/another_subdir/meat t/swamp/groceries/dir.d/CVS/fruit t/swamp/groceries/dir.d/CVS/junk t/swamp/groceries/dir.d/CVS/meat t/swamp/groceries/dir.d/fruit t/swamp/groceries/dir.d/junk t/swamp/groceries/dir.d/meat t/swamp/groceries/dir.d/RCS/fruit t/swamp/groceries/dir.d/RCS/junk t/swamp/groceries/dir.d/RCS/meat t/swamp/groceries/fruit t/swamp/groceries/junk t/swamp/groceries/meat t/swamp/groceries/subdir/fruit t/swamp/groceries/subdir/junk t/swamp/groceries/subdir/meat t/swamp/html.htm t/swamp/html.html t/swamp/incomplete-last-line.txt t/swamp/javascript.js t/swamp/lua-shebang-test t/swamp/minified.js.min t/swamp/minified.min.js t/swamp/moose-andy.jpg t/swamp/not-an-#emacs-workfile# t/swamp/notaMakefile t/swamp/notaRakefile t/swamp/notes.md t/swamp/options-crlf.pl t/swamp/options.pl t/swamp/options.pl.bak t/swamp/perl-test.t t/swamp/perl-without-extension t/swamp/perl.cgi t/swamp/perl.handler.pod t/swamp/perl.pl t/swamp/perl.pm t/swamp/perl.pod t/swamp/perl.tar.gz t/swamp/perltoot.jpg t/swamp/pipe-stress-freaks.F t/swamp/sample.asp t/swamp/sample.aspx t/swamp/sample.rake t/swamp/service.svc t/swamp/solution8.tar t/swamp/stuff.cmake t/swamp/swamp/ignoreme.txt t/text/amontillado.txt t/text/bill-of-rights.txt t/text/constitution.txt t/text/gettysburg.txt t/text/number.txt t/text/numbered-text.txt t/text/ozymandias.txt t/text/raven.txt xt/coding-standards.t xt/coresubs.t xt/man.t xt/pod.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) ack-v3.5.0/README.md0000644000175100017510000000501014023040515012362 0ustar andyandy# ack 3 ack is a code-searching tool, similar to grep but optimized for programmers searching large trees of source code. It is highly portable and runs on any platform that runs Perl. ack is written and maintained by Andy Lester (andy@petdance.com). * [Project home page](https://beyondgrep.com/) * [Code home page](https://github.com/beyondgrep/ack3) * [Issue tracker](https://github.com/beyondgrep/ack3/issues) * Mailing lists * [ack-announce](https://groups.google.com/d/forum/ack-announce), announcements-only * [ack-users](https://groups.google.com/d/forum/ack-users), for users of ack * [ack-dev](https://groups.google.com/d/forum/ack-dev), for ack development * [Build status ![Build Status](https://github.com/beyondgrep/ack3/workflows/testsuite/badge.svg?branch=dev)](https://github.com/beyondgrep/ack3/actions?query=workflow%3Atestsuite+branch%3Adev) * [CPAN Testers](https://cpantesters.org/distro/A/ack.html) # Building ack requires Perl 5.10.1 or higher, and it requires the [File::Next](https://metacpan.org/pod/File::Next) module to be installed. ## Checking prerequisites To check ack's dependencies, run this command in the shell: perl -MFile::Next -E'say "ack is ready to build!"' If everything is OK, you'll see: ack is ready to build! If your installation of Perl is outdated, you'll see an error like this: Unrecognized switch: -Esay "ack is ready to build!" (-h will show valid options). If you don't have File::Next installed, you'll see an error like this: Can't locate File/Next.pm in @INC (@INC contains: /home/andy/... BEGIN failed--compilation aborted. and you'll need to install File::Next yourself: # Install File::Next dependency perl -MCPAN -e install File::Next ## Building ack If you've got a recent enough version of Perl and you have File::Next installed, you can build ack. # Required perl Makefile.PL make make test sudo make install # For a system-wide installation # - or - make ack-standalone cp ack-standalone ~/bin/ack3 # For a personal installation # Development * [How to contribute](CONTRIBUTING.md) * [Developer's Guide](DEVELOPERS.md) * [Design Guide](DESIGN.md) # Community See the [Community](https://beyondgrep.com/community/) page. # License Copyright 2005-2021 Andy Lester. This program is free software; you can redistribute it and/or modify it under the terms of the [Artistic License v2.0](https://www.perlfoundation.org/artistic_license_2_0). See also the LICENSE.md file that comes with the ack distribution. ack-v3.5.0/META.yml0000664000175100017510000000217214023040526012366 0ustar andyandy--- abstract: 'A grep-like program for searching source code' author: - 'Andy Lester ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.60, CPAN::Meta::Converter version 2.143240' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: ack no_index: directory: - t - inc requires: Cwd: '3.00' File::Basename: '1.00015' File::Next: '1.18' File::Spec: '3.00' File::Temp: '0.19' Getopt::Long: '2.38' List::Util: '0' Pod::Perldoc: '3.20' Pod::Text: '0' Pod::Usage: '1.26' Scalar::Util: '0' Term::ANSIColor: '1.10' Test::Harness: '2.50' Test::More: '0.98' Text::ParseWords: '3.1' if: '0' parent: '0' perl: '5.010001' version: '0' resources: MailingList: https://groups.google.com/group/ack-users bugtracker: https://github.com/beyondgrep/ack3 homepage: https://beyondgrep.com/ license: https://www.perlfoundation.org/artistic-license-20.html repository: git://github.com/beyondgrep/ack3.git version: v3.5.0 ack-v3.5.0/META.json0000664000175100017510000000362314023040526012540 0ustar andyandy{ "abstract" : "A grep-like program for searching source code", "author" : [ "Andy Lester " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.60, CPAN::Meta::Converter version 2.143240", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "ack", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Cwd" : "3.00", "File::Basename" : "1.00015", "File::Next" : "1.18", "File::Spec" : "3.00", "File::Temp" : "0.19", "Getopt::Long" : "2.38", "List::Util" : "0", "Pod::Perldoc" : "3.20", "Pod::Text" : "0", "Pod::Usage" : "1.26", "Scalar::Util" : "0", "Term::ANSIColor" : "1.10", "Test::Harness" : "2.50", "Test::More" : "0.98", "Text::ParseWords" : "3.1", "if" : "0", "parent" : "0", "perl" : "5.010001", "version" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/beyondgrep/ack3" }, "homepage" : "https://beyondgrep.com/", "license" : [ "https://www.perlfoundation.org/artistic-license-20.html" ], "repository" : { "type" : "git", "url" : "git://github.com/beyondgrep/ack3.git" }, "x_MailingList" : "https://groups.google.com/group/ack-users" }, "version" : "v3.5.0" }