Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Message
| I wanted to get this project finished, so I wrote another bit of Lua code to try to detect the cases where the "before" and "after" of my automated changes were not identical, and then follow those ones up.
This slightly hacky bit of code below does the trick:
-- pattern to detect a function declaration
pat = "[%a_]+%s+%*?%s*([%a%d_]+)%s*%b().-(%b{})"
olddir = "C:\\smaugfuss\\src\\"
snprintf1 = "snprintf%s*%(%s*([%a%d_]+)%s*,%s*("
snprintf2 = "snprintf%s*%(%s*([%a%d_]+)%s*%+%s*strlen%s*%(%s*%1%s*%)%s*,%s*("
found = 0
not_found = 0
replacements = {
{ find = snprintf1 .. "%d+)%s*,",
},
{ find = snprintf1 .. "MAX_%u+_LENGTH)%s*,",
},
{ find = snprintf1 .. "SMST)%s*,",
},
{ find = snprintf1 .. "LGST)%s*,",
},
{ find = snprintf1 .. "IMC_BUFF_SIZE)%s*,",
},
{ find = snprintf2 .. "IMC_BUFF_SIZE)%s*%-%s*strlen%s*%(%s*%1%s*%)%s*,",
},
{ find = snprintf2 .. "%(?%s*MAX_%u+_LENGTH)%s*%-%s*strlen%s*%(%s*%1%s*%)%s*%)?%s*,",
},
{ find = snprintf2 .. "LGST)%s*%-%s*strlen%s*%(%s*%1%s*%)%s*,",
},
} -- end replacements table
function check_arg (s, size)
match = string.find (saved_body,
"char%s+" .. s .. "%s*%[%s*" ..
size .. "%s*%]")
if match then
found = found + 1
else
not_found = not_found + 1
key = s .. ":" .. size
if not reported [key] then
reported [key] = true
ColourNote ("white", "red",
"Cannot find declaration for " .. s .. " (size " .. size ..
") in function " .. saved_name
)
end -- if not already reported it
end -- if
end -- check_arg
function process_function (name, body)
-- Note (" +++ function: " .. name)
reported = {}
saved_name = name -- in case we need to report it
saved_body = body -- move to global scope for check_arg
-- check each change
for k, v in ipairs (replacements) do
s, count = string.gsub (body, v.find, check_arg)
file_count = file_count + count
end -- for each replacement
end -- process_function
function process_file (name)
local f, s
file_count = 0
print ("Processing: " .. name)
f = assert (io.open (olddir .. name, "rb")) -- open input
s = f:read ("*a") -- read all of it
f:close () -- close it
-- fix up imc strange function defs
s = string.gsub (s, "PFUN%( ([%a%d_]+) %)",
"void %1( IMC_PACKET *q, char *packet )")
s = string.gsub (s, "IMC_CMD%( ([%a%d_]+) %)",
"void %1( CHAR_DATA *ch, char *argument )")
s = string.gsub (s, "'}'", "") -- confuses function finding
string.gsub (s, pat, process_function)
print (" -- " .. file_count .. " changes found")
end -- process_file
print (string.rep ("-", 60))
local t = assert (utils.readdir (olddir .. "*.c"))
local k
for k in pairs (t) do
process_file (k)
end -- for
Note ("Matches found = ", found)
Note ("No declaration found = ", not_found)
What this is trying to do is break up each file into a function declaration and body of the general form:
return_type name ( args ) { body }
It then scans each function body for the "snprintf" declarations, and for each individual one, then rescans the function body to try to find a local declaration of the form:
char <name> [ <size> ]
For example, if it locates:
snprintf( buf, MAX_STRING_LENGTH, "%s\r\n", pArea->resetmsg );
Then the name is "buf" and the size is "MAX_STRING_LENGTH".
So, it looks for:
char buf [MAX_STRING_LENGTH]
If it finds this (bearing in mind it must be inside the same function), then it assumes that it was a local declaration, and all is well.
There are a couple of kludgy aspects to this, in particular in the file imc.c a lot of function declarations are done using defines, like this:
PFUN( imc_recv_tell )
Thus there is a bit of pre-processing to put those back into standard function form.
Running this script on my copy of SmaugFUSS gave these results:
Processing: save.c
-- 11 changes found
Processing: act_obj.c
-- 13 changes found
Processing: hashstr.c
-- 3 changes found
Processing: shops.c
-- 24 changes found
Processing: comm.c
Cannot find declaration for pbuf (size MAX_STRING_LENGTH) in function display_prompt
-- 21 changes found
Processing: mud_prog.c
Cannot find declaration for rval (size MAX_STRING_LENGTH) in function isoperator
-- 6 changes found
Processing: planes.c
-- 0 changes found
Processing: skills.c
-- 29 changes found
Processing: fight.c
Cannot find declaration for buf2 (size 256) in function new_dam_message
Cannot find declaration for buf3 (size 256) in function new_dam_message
-- 22 changes found
Processing: act_wiz.c
Cannot find declaration for buf (size ( MAX_STRING_LENGTH) in function do_owhere
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function do_bestow
Cannot find declaration for reboot_time (size 50) in function get_reboot_string
Cannot find declaration for arg2 (size MAX_INPUT_LENGTH) in function do_sedit
Cannot find declaration for buf (size ( MAX_STRING_LENGTH) in function do_ipcompare
-- 88 changes found
Processing: handler.c
-- 7 changes found
Processing: const.c
-- 0 changes found
Processing: mud_comm.c
-- 16 changes found
Processing: act_comm.c
Cannot find declaration for lbuf (size MAX_STRING_LENGTH) in function talk_channel
-- 31 changes found
Processing: imm_host.c
-- 0 changes found
Processing: services.c
-- 2 changes found
Processing: polymorph.c
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function do_morphset
-- 5 changes found
Processing: sha256.c
-- 0 changes found
Processing: boards.c
-- 22 changes found
Processing: act_info.c
Cannot find declaration for buf (size ( MAX_STRING_LENGTH) in function do_exits
-- 34 changes found
Processing: interp.c
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function write_watch_files
Cannot find declaration for cmd_flag_buf (size MAX_STRING_LENGTH) in function check_cmd_flags
-- 10 changes found
Processing: mapout.c
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function count_lines
-- 1 changes found
Processing: imc.c
Cannot find declaration for buf2 (size LGST) in function imclog
Cannot find declaration for buf2 (size LGST) in function imcbug
Cannot find declaration for buf (size LGST) in function imc_recv_tell
Cannot find declaration for buf (size LGST) in function update_imchistory
Cannot find declaration for name (size SMST) in function imc_display_channel
Cannot find declaration for buf (size IMC_BUFF_SIZE) in function imc_recv_who
Cannot find declaration for lbuf2 (size LGST) in function imcfread_config_file
Cannot find declaration for to (size SMST) in function imccommand
Cannot find declaration for buf (size LGST) in function imcsetup
Cannot find declaration for buf1 (size LGST) in function imctell
Cannot find declaration for to (size SMST) in function imcremoteadmin
Cannot find declaration for buf (size LGST) in function imc_send_social
-- 107 changes found
Processing: build.c
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function edit_buffer
-- 57 changes found
Processing: mpxset.c
-- 26 changes found
Processing: magic.c
-- 16 changes found
Processing: hotboot.c
Cannot find declaration for buf2 (size 100) in function do_hotboot
Cannot find declaration for buf3 (size 100) in function do_hotboot
-- 10 changes found
Processing: deity.c
-- 12 changes found
Processing: update.c
-- 16 changes found
Processing: act_move.c
-- 10 changes found
Processing: special.c
-- 7 changes found
Processing: color.c
-- 57 changes found
Processing: misc.c
-- 3 changes found
Processing: makeobjs.c
-- 7 changes found
Processing: reset.c
Cannot find declaration for objname (size MAX_STRING_LENGTH) in function sprint_reset
-- 14 changes found
Processing: comments.c
-- 0 changes found
Processing: mccp.c
-- 0 changes found
Processing: player.c
Cannot find declaration for buf (size MAX_STRING_LENGTH) in function do_statreport
-- 163 changes found
Processing: db.c
Cannot find declaration for buf (size ( MAX_STRING_LENGTH) in function bug
Cannot find declaration for buf (size ( MAX_STRING_LENGTH) in function boot_log
-- 27 changes found
Processing: track.c
-- 8 changes found
Processing: clans.c
-- 13 changes found
Processing: tables.c
-- 7 changes found
Processing: ban.c
-- 4 changes found
Matches found = 834
No declaration found = 75
As you can see there were a handful reported (75 counted but duplicates were suppressed from the display).
I then went through to see if any of the automated conversions were likely to be wrong (ie. converting from the original values to "sizeof (buf)". Most could be accounted for by the fact that the function used this syntax:
char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
In this case "arg2" does not match my test (it is not directly preceded by "char") however it is obviously still correct.
However I have detected 5 cases where I think the actual SMAUG code (in its current form) is wrong. See next post for those. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|