ID:2164528
 
Code:
/client/proc/getAllCodeFiles(var/file as file)
set name = "USE THIS ONE"
set category = "Admin"

var/list/files = list()
var/text = file2text(file)
var/regex/r1 = regex("^#include \"(.*)\"$", "gm")
var/regex/r2 = regex("\\.dm$", "g")
while(r1.Find(text))
if(r2.Find(r1.group[0])) files += r1.group[0]

for(var/f in files)
fcopy(f, "shittocheckout.txt")

getAllUsedIcons("shittocheckout.txt")

/client/proc/getAllUsedIcons(var/file as file)
set name = "OR THIS ONE"
set category = "Admin"

var/list/iconsUsed = list()
var/text = file2text(file)

var/regex/r1 = regex("^\\s*?icon_state = \"(.*?)\"$", "gm")

while(r1.Find(text))
if(!iconsUsed.Find(r1.group[0])) iconsUsed += r1.group[0]

world << iconsUsed


Problem description:
I'm trying to get a list of every single icon in the code. To do so, I figured if I could get all of the code files into the same txt file, then I could search through them with a regex and get a list of what I've got, but for some reason the r1.Find() under getAllCodeFiles() only executes once and does nothing (known by using the profiler, only one instance of /regex/Find() when the code is called). What's wrong or what is a better way to do what I'm doing?
I don't think I really agree with having your code stored in a text file. It just seems unnecessary considering DM is capable of scanning through .dm files.

I'm not entirely sure what your desired end result is, and I'm not too familiar with regular expressions; so I just outright scripted something different as opposed to try and find what was causing your existing code errors.

As for whether this is the best method, it's doubtful. However, what this will do is scan your base folder (didn't feel like branching into other subfolders) for .dm files. It will then search the .dm files for the file flag ' ', and if it determines it is indeed an image file (dmi, bmp, png, gif) it will store the icon in a list and then output the list contents.

There are two verb's here. ScanFiles and ScanFiles2. The only difference is ScanFiles only tells you which files are being used, while ScanFiles2 tells you how many times. As stated, I don't really know what your end result is suppose to be.


mob/verb/ScanFiles()
var/list/icon_types = list(".dmi",".bmp",".png",".gif")
var/list/icons = new/list
for(var/v in flist(""))
if(findtext(v,".dm",length(v)-2))
// only check .dm files
var/code = file2text(v)
var/start = 1
for(var/i=length(code)/4;i>0;i--)
start = findtext(code,"'",start)
if(start == 0)
break
var/end = findtext(code,"'",start+1)
if(end == 0 || end-start > 30) //30 characters seems excessive for a file name. May be inside of a text. Also prevents roleback.
start++
continue
var/filename = copytext(code,start+1,end)
var/filetype = copytext(filename,findtext(filename,".",-4,))
if(filetype in icon_types)
icons |= copytext(code,start+1,end)
start = end+1

for(var/i in icons)
src << i


mob/verb/ScanFiles2()
var/list/icon_types = list(".dmi",".bmp",".png",".gif")
var/list/icons = new/list
for(var/v in flist(""))
if(findtext(v,".dm",length(v)-2))
// only check .dm files
var/code = file2text(v)
var/start = 1
for(var/i=length(code)/4;i>0;i--)
start = findtext(code,"'",start)
if(start == 0)
break
var/end = findtext(code,"'",start+1)
if(end == 0 || end-start > 30) //30 characters seems excessive for a file name. May be inside of a text. Also prevents roleback.
start++
continue
var/filename = copytext(code,start+1,end)
var/filetype = copytext(filename,findtext(filename,".",-4,))
if(filetype in icon_types)
icons[copytext(code,start+1,end)] ++
start = end+1

for(var/i in icons)
src << "[i] is found [icons[i]] time\s."


I put some comments in the code, but their haphazard due to me being a tad bit tired. I do hope this helps you in some way though.

Oh, as a side note, this will only work if the server running it is from the source code. Meaning, in the server's root directory, you can find the scripts.
Can't you just use Find (Ctrl+F) in Dream Maker? It supports regex too.
getAllUsedIcons() has a couple of noticeable problems. Namely, you're looking at icon_state instead of icon, and you're also expecting whitespace that may or may not be there. Instead of the space, you should use \s* since that says whitespace is optional.
In response to Ss4toby
So with this, in order to expand it all all subdirectories, should I try something like flist(flist("")) while flist("").len != 0
Here, would this work?
/client/proc/getAllUsedIconStates()
set name = "getAllUsedIconStates"
set category = "Admin"

var/regex/r1 = regex("^.*?icon_state\\s*?=\\s*?\"(.*?)\".*?$", "gm")

world << checkAllSubdirectories("code", r1)

/client/proc/getAllUsedIcons()
set name = "getAllUsedIcons"
set category = "Admin"

var/regex/r1 = regex("^.*?icon\\s*?=\\s*?\"(.*?)\".*?$", "gm")

world << checkAllSubdirectories("code", r1)

/proc/checkAllSubdirectories(var/directory, var/regex/r1)
var/list/toReturn = list()

var/list/files = flist(directory)

if(files.len != 0)
for(var/file in files)
toReturn += checkAllSubdirectories(file, r1)

else
var/text = file2text(directory)
while(r1.find(text)) toReturn += r1.group[0]

return toReturn

(for reference there's a folder called "code" in the same directory as the DME, and it has all of the code files beneath it)

Also, @Kaiochao, in theory yes, but this ultimately would take a lot less time considering I have to deal with SS13's hundreds of files of spaghetti and it compiles the list for me instead of writing it down or something
In response to Mad Snail Disease
Mad Snail Disease wrote:
Also, @Kaiochao, in theory yes, but this ultimately would take a lot less time considering I have to deal with SS13's hundreds of files of spaghetti and it compiles the list for me instead of writing it down or something

The "Find All" function gives you a list of all occurrences in the compiler output. You can even double-click a line to go to that line in the code.
In response to Kaiochao
Right you are, I guess this is irrelevant then.
if you use git (which you should be if you're working on ss13) you can git grep which will search through all files and through the repo history as well depending on the command line arguments you pass it.
I'm not really a fan of the git search function, it's a little meh
It's extremely fast and can accept regex, I don't see how you'd get much better.