Posts: 602
Threads: 27
Joined: Oct 2004
Code: '------------------------------------------------------------------------------------------
ALMIGHTY MULTIPLE FILE LINE COUNTER
Version 11.23
written by
the incredible blitz
le marzec
'------------------------------------------------------------------------------------------
A brief history
---------------
it was the time of the big war, with the 10 rings and the dwarfs and all that, when
two little hobits decided to change the destiny of their land. they packed their bags
and went on a journey to seek the ultimate weapon to show off.
and they came back with this: the almighty multiple file line counter version 11.23
"but tell me oh mighty creators, what can it do?" you may ask. and the answer is a lot
it can open files, list directories and PRINT OUT TO THE FUCKING SCREEN! you are right,
to the screen...
yeah and it can count the lines from all the files you specified via search patterns. and
uhm it even has a nifty commandline parser and stuff. blitz wanted that to show off, as
always...
how to use this almighty weapon?
--------------------------------
well first you can specify wheter you want to take all the subdirectories recursively into
account. like with an "-r" or an "-d" whatever you want. next you can specify matching
patters as you are used with the dir command on win32/dos and seperate several of them via
a space.
so if you want to count all the bas and bi files in a directory and want to know how
many god like lines of code you have already coded just do this
wc *.bas *.bi
and bang it tells you how many files of that types are in the current directory and
how many lines and bytes they contain in total
to search through subdirectories too you invoke this like
wc -r *.bas *.bi
for example.
well our quest is over, we now waste all our gold on virgins and grok.
later...
you can find that crap on http://ratatoskr.dragonhill.cc/fbirc/wc.rar
quote="NecrosIhsan"]
[/quote]
Posts: 922
Threads: 15
Joined: Jun 2003
Omg, hobits again, i thought they were all dead, damnit.
Nice, btw, you could have used DIR$(), it supports wildcards too -- but yeah, nothing beats being recursive for free using SHELL "DIR -r" :P
Posts: 1,439
Threads: 15
Joined: Apr 2003
Quote:well our quest is over, we now waste all our gold on virgins and grok.
I'm thinkin' grog, unless I underestimate you guys...
Posts: 451
Threads: 16
Joined: Feb 2003
erm, I don't mean to be a wet blanket, but...what useful purpose does this serve, again?
Life is like a box of chocolates', hrm, WTF, no it isn't, more like, 'life is like a steaming pile of horse crap.'
Posts: 2,771
Threads: 96
Joined: Oct 2003
It counts up the total number of lines of code in a project, that may consist of several modules.
As far as I can see, anyway...
Posts: 10
Threads: 0
Joined: May 2005
Compiles & runs with FreeBASIC 0.14b, probably works with other versions. Only minimally tested. :-)
Code: Option Explicit
'$Include: 'win/kernel32.bi'
Declare Sub InitTable()
Declare Sub ProcessCommandLine()
Declare Sub ProcessCommandLineItem(item$)
Declare Sub RecursivelyFindFiles(base_path$, spec$)
Declare Sub RecursivelyFindSubdirs(base_path$, subdir_spec$, remaining_spec$)
Declare Sub ProcessFile(path_to_file$)
Declare Sub OutputStatistics(lines As LongInt, words As LongInt, characters As LongInt, label$)
Declare Function MinimumNonZero(a&, b&) As Long
Const FLAG_COUNT_LF_1% = 1
Const FLAG_COUNT_SPACE_1% = 2
Const FLAG_COUNT_CRLF_2% = 4
Const FLAG_COUNT_SPACE_2% = 8
Const FLAG_COUNT_CR_1% = 16
Const FLAG_ENABLE_NEXT_LF_1% = 32
Const FLAG_ENABLE_NEXT_SPACE_1% = 64
Const FLAG_ALWAYS_ON% = 128
Dim Shared table(0 To 65535) As UByte
Dim Shared As LongInt total_lines, total_words, total_characters
Dim Shared show_lines%, show_words%, show_characters%, num_files&
Const FILE_ATTR_DIRECTORY% = 16
Const FILE_ATTR_ARCHIVE% = 32
InitTable
ProcessCommandLine
Sub InitTable()
Dim i&, a$, byte1%, byte2%
For i& = 0 To 65535
table(i&) = FLAG_ALWAYS_ON% Or FLAG_ENABLE_NEXT_LF_1% Or FLAG_ENABLE_NEXT_SPACE_1%
a$ = MKI$(i&)
byte1% = Asc(a$)
byte2% = Asc(a$, 2)
Select Case byte1%
Case 13: table(i&) = table(i&) Or FLAG_COUNT_SPACE_1% Or FLAG_COUNT_CR_1%
Case 10: table(i&) = table(i&) Or FLAG_COUNT_SPACE_1% Or FLAG_COUNT_LF_1%
Case 32: table(i&) = table(i&) Or FLAG_COUNT_SPACE_1%
End Select
Select Case byte2%
Case 13:
table(i&) = table(i&) Or FLAG_COUNT_CRLF_2%
table(i&) = table(i&) And Not FLAG_ENABLE_NEXT_LF_1%
Case 10:
If byte1% <> 13 Then table(i&) = table(i&) Or FLAG_COUNT_CRLF_2%
End Select
Select Case byte2%
Case 13, 10, 32:
table(i&) = table(i&) And Not FLAG_ENABLE_NEXT_SPACE_1%
Select Case byte1%
Case 13, 10, 32: ' do nothing
Case Else:
table(i&) = table(i&) Or FLAG_COUNT_SPACE_2%
End Select
End Select
Next i&
End Sub
Sub ProcessCommandLine()
Dim show_all%
Dim cmd$, in_string%, i&, c%, word$, word_length%
show_all% = -1
show_lines% = 0
show_words% = 0
show_characters% = 0
in_string% = 0
cmd$ = Trim$(Command$)
While Asc(cmd$) = 45 ' the '-' character
show_all% = 0
For i& = 2 To Len(cmd$)
c% = Asc(cmd$, i&)
Select Case c%
Case 32:
cmd$ = LTrim$(Mid$(cmd$, i& + 1))
Exit For
Case 108: ' the 'l' character, for lines
show_lines% = -1
Case 119: ' the 'w' character, for words
show_words% = -1
Case 99: ' the 'c' character, for characters
show_characters% = -1
Case Else:
Print "Usage: wc [-lwc] [filename ...]"
End
End Select
Next i&
WEnd
If show_all% Then
show_lines% = -1
show_words% = -1
show_characters% = -1
End If
word$ = Space$(10)
word_length% = 0
For i& = 1 To Len(cmd$)
c% = Asc(cmd$, i&)
If in_string% Then
If c% = 34 Then
in_string% = 0
Else
word_length% = word_length% + 1
If word_length% > Len(word$) Then word$ = word$ + Space$(10)
Mid$(word$, word_length%, 1) = Chr$(c%)
End If
Else
If c% = 34 Then
in_string% = 0
ElseIf c% = 32 Then
If word_length% Then ProcessCommandLineItem Left$(word$, word_length%)
word_length% = 0
Else
word_length% = word_length% + 1
If word_length% > Len(word$) Then word$ = word$ + Space$(10)
Mid$(word$, word_length%, 1) = Chr$(c%)
End If
End If
Next i&
If word_length% Then ProcessCommandLineItem Left$(word$, word_length%)
If num_files& > 1 Then OutputStatistics total_lines, total_words, total_characters, "total"
End Sub
Sub ProcessCommandLineItem(item$)
Dim i&, c%
If Abs(Asc(item$, Len(item$)) * 2 - 139) = 45 Then ' fancy way of saying "is either '/' or '\'"
Exit Sub ' if the spec ends in a divider, then no files are named
End If
If Len(item$) > 3 Then
If (Asc(item$, 2) = 58) And Abs(Asc(item$, 3) * 2 - 139) = 45 Then
For i& = 4 To Len(item$)
c% = Asc(item$, i&)
If (c% <> 47) And (c% <> 92) Then
RecursivelyFindFiles Left$(item$, 2) + "\", Mid$(item$, i&)
Exit For
End If
Next i&
End If
Else
Select Case Asc(item$, 1)
Case 47, 92: ' the '/' and '\' characters, respectively
For i& = 2 To Len(item$)
c% = Asc(item$, i&)
If (c% <> 47) And (c% <> 92) Then
RecursivelyFindFiles "\", Mid$(item$, i&)
Exit For
End If
Next i&
Case Else:
RecursivelyFindFiles "", item$
End Select
End If
End Sub
Function MinimumNonZero(a&, b&) As Long
If a& = 0 Then
MinimumNonZero = b&
ElseIf b& = 0 Then
MinimumNonZero = a&
ElseIf a& < b& Then
MinimumNonZero = a&
Else
MinimumNonZero = b&
End If
End Function
Sub RecursivelyFindFiles(base_path$, spec$)
Dim divider&, this_spec$, next_spec$
divider& = MinimumNonZero(InStr(spec$, "/"), InStr(spec$, "\"))
If divider& > 0 Then
this_spec$ = Left$(spec$, divider& - 1)
While Abs(Asc(spec$, divider&) * 2 - 139) = 45 ' fancy way of saying "is either '/' or '\'"
divider& = divider& + 1 ' we know the spec doesn't end in a divider because ProcessCommandLineItem checks that
WEnd
next_spec$ = Mid$(spec$, divider&)
RecursivelyFindSubdirs base_path$, this_spec$, next_spec$
Else
Dim filename$, full_filename$
filename$ = Dir$(base_path$ + spec$, -1)
While Len(filename$) <> 0
full_filename$ = base_path$ + filename$
If (GetFileAttributes(full_filename$) And FILE_ATTR_DIRECTORY%) = 0 Then ProcessFile full_filename$
filename$ = Dir$("", -1)
WEnd
End If
End Sub
Sub RecursivelyFindSubdirs(base_path$, subdir_spec$, remaining_spec$)
Dim num_subdirs%, subdirname$, i&
ReDim subdirs$(10)
num_subdirs% = 0
subdirname$ = Dir$(base_path$ + subdir_spec$, -1)
While Len(subdirname$) <> 0
If (GetFileAttributes(base_path$ + subdirname$) And FILE_ATTR_DIRECTORY%) <> 0 Then
If (subdirname$ <> ".") And (subdirname$ <> "..") Then
num_subdirs% = num_subdirs% + 1
If num_subdirs% > UBound(subdirs$) Then ReDim Preserve subdirs$(num_subdirs% + 10)
subdirs$(num_subdirs%) = base_path$ + subdirname$ + "\"
End If
End If
subdirname$ = Dir$("", -1)
WEnd
For i& = 1 To num_subdirs%
RecursivelyFindFiles subdirs$(i&), remaining_spec$
Next i&
End Sub
Sub ProcessFile(path_to_file$)
Dim ff%, state%, remaining&, i&
Dim As LongInt file_lines, file_words, file_characters
Dim buffer As String * 32768
Dim buf_ptr As UShort Ptr
buf_ptr = VarPtr(buffer)
num_files& = num_files& + 1
ff% = FreeFile
state% = FLAG_ALWAYS_ON% Or FLAG_ENABLE_NEXT_LF_1% Or FLAG_ENABLE_NEXT_SPACE_1%
Open path_to_file$ For Binary As #ff%
remaining& = LOF(ff%)
file_characters = remaining&
total_characters = total_characters + file_characters
While remaining& > 32768
Get #ff%, , buffer
remaining& = remaining& - 32768
For i& = 0 To 16383
state% = ((state% SHR 5) Or &HF8) And table(buf_ptr[i&])
If state% And FLAG_COUNT_CR_1% Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If state% And FLAG_COUNT_LF_1% Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If state% And FLAG_COUNT_CRLF_2% Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If state% And FLAG_COUNT_SPACE_1% Then
file_words = file_words + 1
total_words = total_words + 1
End If
If state% And FLAG_COUNT_SPACE_2% Then
file_words = file_words + 1
total_words = total_words + 1
End If
Next i&
WEnd
Get #ff%, , buffer
If (remaining& And 1) <> 0 Then
buf_ptr[remaining& SHR 1] = buf_ptr[remaining& SHR 1] And &HFF
End If
For i& = 0 To (remaining& + 1) SHR 1
state% = ((state% SHR 5) Or &HF8) And table(buf_ptr[i&])
If (state% And FLAG_COUNT_CR_1%) <> 0 Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If (state% And FLAG_COUNT_LF_1%) <> 0 Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If (state% And FLAG_COUNT_CRLF_2%) <> 0 Then
file_lines = file_lines + 1
total_lines = total_lines + 1
End If
If (state% And FLAG_COUNT_SPACE_1%) <> 0 Then
file_words = file_words + 1
total_words = total_words + 1
End If
If (state% And FLAG_COUNT_SPACE_2%) <> 0 Then
file_words = file_words + 1
total_words = total_words + 1
End If
Next i&
If (state% And FLAG_ENABLE_NEXT_SPACE_1%) <> 0 Then
file_words = file_words + 1
total_words = total_words + 1
End If
Close #ff%
OutputStatistics file_lines, file_words, file_characters, path_to_file$
End Sub
Sub OutputStatistics(lines As LongInt, words As LongInt, characters As LongInt, label$)
If show_lines% Then Print Using "####### "; lines;
If show_words% Then Print Using "######## "; words;
If show_characters% Then Print Using "######### "; characters;
Print label$
End Sub
|