;--- simple masm source to html converter. Public Domain.
;--- it's a sample for a mixed-language application (uses CRT)
;--- Win32 binary:
;--- assemble: jwasm -coff masm2htm.asm
;--- link: link /subsystem:console masm2htm.obj \msvc\lib\libc.lib
;--- Linux binary:
;--- assemble: jwasm -zcw -elf -Fo masm2htm.o masm2htm.asm
;--- link: gcc -o masm2htm masm2htm.o
.386
.model FLAT, c
option casemap:none
printf proto c :ptr BYTE, :VARARG
fopen proto c :ptr BYTE, :ptr BYTE
fclose proto c :ptr
fseek proto c :ptr, :DWORD, :DWORD
ftell proto c :ptr
fread proto c :ptr BYTE, :DWORD, :DWORD, :ptr
fwrite proto c :ptr BYTE, :DWORD, :DWORD, :ptr
strcat proto c :ptr BYTE, :ptr BYTE
strcpy proto c :ptr BYTE, :ptr BYTE
strlen proto c :ptr BYTE
_stricmp proto c :ptr BYTE, :ptr BYTE
malloc proto c :DWORD
free proto c :ptr
if 1
externdef c errno:dword
else
;--- if errno is to be defined as a function call
__errno macro
__errno_location proto c ;this is the gcc name
call __errno_location
mov eax,[eax]
exitm <eax>
endm
errno textequ <__errno()>
endif
lf equ 10
cr equ 13
SEEK_SET equ 0
SEEK_END equ 2
NULL equ 0
EOL equ <cr,lf>
CStr macro text
local xxx
.const
xxx db text,0
.code
exitm <offset xxx>
endm
@DD macro list:VARARG
for directive, <list>
local xxx
.const
xxx db @CatStr(!",directive,!"),0
.data
dd offset xxx
endm
endm
.data
;--- array of directives which are to be displayed "bold"
dirtab label dword
@DD <.186>, <.286>, <.286c>, <.286p>
@DD <.287>, <.386>, <.386c>, <.386p>
@DD <.387>, <.486>, <.486p>, <.586>
@DD <.586p>, <.686>, <.686p>, <.8086>
@DD <.8087>, <.allocstack>, <.alpha>, <.break>
@DD <.code>, <.const>, <.continue>, <.cref>
@DD <.data>, <.data?>, <.dosseg>, <.else>
@DD <.elseif>, <.endif>, <.endprolog>, <.endw>
@DD <.err>, <.err1>, <.err2>, <.errb>
@DD <.errdef>, <.errdif>, <.errdifi>, <.erre>
@DD <.erridn>, <.erridni>, <.errnb>, <.errndef>
@DD <.errnz>, <.exit>, <.fardata>, <.fardata?>
@DD <.if>, <.k3d>, <.lall>, <.lfcond>
@DD <.list>, <.listall>, <.listif>, <.listmacro>
@DD <.listmacroall>, <.mmx>, <.model>, <.no87>
@DD <.nocref>, <.nolist>, <.nolistif>, <.nolistmacro>
@DD <.pushframe>,<.pushreg>, <.radix>, <.repeat>
@DD <.safeseh>, <.sall>, <.savereg>, <.savexmm128>
@DD <.seq>, <.setframe>, <.sfcond>, <.stack>
@DD <.startup>, <.tfcond>, <.until>, <.untilcxz>
@DD <.while>, <.x64>, <.x64p>, <.xall>
@DD <.xcref>, <.xlist>, <.xmm>
@DD <alias>, <align>, <assume>, <catstr>
@DD <comm>, <comment>, <db>, <dd>
@DD <df>, <dosseg>, <dq>, <dt>
@DD <dw>, <echo>, <else>, <elseif>
@DD <elseif1>, <elseif2>, <elseifb>, <elseifdef>
@DD <elseifdif>, <elseifdifi>,<elseife>, <elseifidn>
@DD <elseifidni>,<elseifnb>, <elseifndef>, <end>
@DD <endif>, <endm>, <endp>, <ends>
@DD <equ>, <even>, <exitm>, <extern>
@DD <externdef>, <extrn>, <for>, <forc>
@DD <goto>, <group>, <if>, <if1>
@DD <if2>, <ifb>, <ifdef>, <ifdif>
@DD <ifdifi>, <ife>, <ifidn>, <ifidni>
@DD <ifnb>, <ifndef>, <incbin>, <include>
@DD <includelib>,<instr>, <invoke>, <irp>
@DD <irpc>, <label>, <local>, <macro>
@DD <name>, <option>, <org>, <page>
@DD <popcontext>,<proc>, <proto>, <public>
@DD <purge>, <pushcontext>,<record>, <repeat>
@DD <rept>, <segment>, <sizestr>, <struc>
@DD <struct>, <substr>, <subtitle>, <subttl>
@DD <textequ>, <title>, <typedef>, <union>
@DD <while>
enddirtab label dword
startstring label byte
db "<!DOCTYPE HTML PUBLIC ",22h,"-//W3C//DTD HTML 3.2 FINAL//EN",22h,">",EOL
db "<HTML>",EOL
db "<HEAD>",EOL
db "<TITLE>"
db 0
startstring2 label byte
db "</TITLE>",EOL
db "</HEAD>",EOL
db "<BODY>",EOL
db "<TABLE BORDER=0 CELLSPACING=4 CELLPADDING=4 WIDTH=",22h,"100%",22h,">",EOL
db "<TR BGCOLOR=#E0E0E0><TD>",EOL
db "<pre>",EOL
db 0
endstring label byte
db "</pre>",EOL
db "</TD></TR>",EOL
db "</TABLE>",EOL
db "</BODY>",EOL
db "</HTML>",EOL
db 0
fgcolorgray label byte
db "<font color=#808080>"
db 0
fgcolorrest label byte
db "</font>"
db 0
.code
is_valid_id_first_char proc stdcall
cmp al,'.'
jz yes
cmp al,'$'
jz yes
cmp al,'?'
jz yes
cmp al,'@'
jz yes
cmp al,'_'
jz yes
cmp al,'A'
jb no
cmp al,'Z'
jbe yes
cmp al,'a'
jb no
cmp al,'z'
jbe yes
no:
stc
ret
yes:
clc
ret
is_valid_id_first_char endp
is_valid_id_char proc stdcall
cmp al,'$'
jz yes
cmp al,'?'
jz yes
cmp al,'@'
jz yes
cmp al,'_'
jz yes
cmp al,'0'
jb no
cmp al,'9'
jbe yes
cmp al,'A'
jb no
cmp al,'Z'
jbe yes
cmp al,'a'
jb no
cmp al,'z'
jbe yes
no:
stc
ret
yes:
clc
ret
is_valid_id_char endp
scandirectives proc stdcall uses esi edi ebx ecx pdir:ptr BYTE
mov esi, offset dirtab
mov edi, pdir
.while (esi < offset enddirtab )
lodsd
push esi
mov esi, eax
invoke _stricmp, esi, edi
and eax, eax
jz found
pop esi
.endw
clc
ret
found:
mov eax, esi
pop esi
stc
ret
scandirectives endp
;--- convert masm text found in buffer
;--- 1. put comments in gray fgcolor
;--- 2. write directives in bold.
;--- 3. convert '<', '>' and '&' to '<', '>' and '&'
convertbuffer proc uses ebx esi edi fname:ptr BYTE, buffer:ptr BYTE, size_:DWORD, psize:ptr DWORD
local outb:dword
local startdir:dword
local firstdir:byte
local lastchar:byte
local inquotes:byte
local inangles:byte
local incomment:byte
local cnt:word
local startline:dword
mov eax, size_
shl eax, 2 ;use size*4 for output buffer size
invoke malloc, eax
.if ( eax == 0 )
invoke printf, CStr(<"out of memory",lf>)
mov ecx, psize
xor eax, eax
mov [ecx], eax
ret
.endif
mov ebx, eax
mov edi, eax
mov startline, edi
mov startdir, 0
mov firstdir, 0
mov inquotes, 0
mov inangles, 0
mov incomment, 0
mov esi, offset startstring
.while ( byte ptr [esi] )
movsb
.endw
mov esi, fname
.while ( byte ptr [esi] )
movsb
.endw
mov esi, offset startstring2
.while ( byte ptr [esi] )
movsb
.endw
mov esi, buffer
mov ecx, size_
.while (ecx)
lodsb
.if ( incomment == 0 && inquotes == 0 && inangles == 0 )
.if ( startdir == 0 )
.if ( firstdir == 0 )
call is_valid_id_first_char
jc @F
mov startdir, edi
@@:
.endif
.else
call is_valid_id_char
.if (CARRY?)
push eax
mov byte ptr [edi], 0
invoke scandirectives, startdir
.if (CARRY?) ;found?
mov firstdir,1
mov edi, startdir
push esi
mov esi, eax
mov ax,"b<"
stosw
mov al,'>'
stosb
.while ( byte ptr [esi] )
movsb
.endw
mov eax,">b/<"
stosd
pop esi
.endif
pop eax
mov startdir, 0
.endif
.endif
.endif
.if ( al == '<' )
mov eax, ";tl&"
stosd
mov al,'<'
.elseif ( al == '>' )
mov eax, ";tg&"
stosd
mov al,'>'
.elseif ( al == '&' )
mov eax, "pma&"
stosd
mov al, ";"
stosb
mov al,'&'
.else
;.if ( incomment != 0 && ( al == cr || al == lf ))
.if ( ( al == cr || al == lf ) && incomment != 0 )
push esi
mov esi, offset fgcolorrest
.while ( byte ptr [esi] )
movsb
.endw
pop esi
.endif
stosb
.endif
.if ( al == lf || al == cr )
mov startline, edi
mov startdir, 0
mov firstdir, 0
mov inquotes, 0
mov inangles, 0
mov incomment, 0
.elseif ( al == ';' && incomment == 0 )
.if ( inquotes == 0 && inangles == 0 )
mov incomment, 1
push esi
mov esi, offset fgcolorgray
.while ( byte ptr [esi] )
movsb
.endw
pop esi
.endif
.elseif ( al == '<' && incomment == 0 && lastchar != '!' )
inc inangles
.elseif ( al == '>' && incomment == 0 && lastchar != '!' && inangles )
dec inangles
.elseif ( al == '"' && incomment == 0 && lastchar != '!' )
.if ( inquotes == al )
mov inquotes, 0
.else
mov inquotes, al
.endif
.elseif ( al == "'" && incomment == 0 && lastchar != '!' )
.if ( inquotes == al )
mov inquotes, 0
.else
mov inquotes, al
.endif
.endif
mov lastchar, al
dec ecx
.endw
mov esi, offset endstring
.while ( byte ptr [esi] )
movsb
.endw
mov eax, ebx
sub edi, eax
mov ecx, psize
mov [ecx], edi
ret
align 4
convertbuffer endp
main proc c argc:dword, argv:ptr ptr
local filename:dword
local filesize:dword
local buffer:dword
local outbuf:dword
local outbsize:dword
local fname[260]:byte
.if ( argc < 2 )
invoke printf, CStr(<"masm2htm v1.0, Public Domain.",lf>)
invoke printf, CStr(<"masm2htm is a masm to html converter.",lf>)
invoke printf, CStr(<"usage: masm2htm input_file [output_file]",lf>)
mov eax,1
ret
.endif
mov ebx,argv
mov ebx,[ebx+1*4]
invoke fopen, ebx, CStr("rb")
.if ( eax )
mov filename, ebx
mov ebx, eax
invoke fseek, ebx, 0, SEEK_END
invoke ftell, ebx
mov filesize, eax
invoke fseek, ebx, 0, SEEK_SET
mov eax, filesize
inc eax
invoke malloc, eax
.if ( eax == 0 )
invoke printf, CStr(<"out of memory",lf>)
invoke fclose, ebx
mov eax,1
ret
.endif
mov buffer, eax
invoke fread, buffer, 1, filesize, ebx
push eax
invoke fclose, ebx
pop eax
.if ( eax != filesize )
invoke printf, CStr(<"read error [%u]",lf>), errno
mov eax,1
ret
.endif
mov edx, buffer
mov byte ptr [edx+eax],0
invoke convertbuffer, filename, buffer, filesize, addr outbsize
push eax
invoke free, buffer
pop eax
.if ( eax )
mov outbuf, eax
mov edx, argv
mov ebx, [edx+1*4]
.if ( argc == 2 )
invoke strlen, ebx
add eax, ebx
.while (eax != ebx && \
byte ptr [eax-1] != ':' && \
byte ptr [eax-1] != '\' && \
byte ptr [eax-1] != '/')
dec eax
.endw
lea ebx, fname
invoke strcpy, ebx, eax
invoke strcat, ebx, CStr(".txt")
.else
mov ebx, argv
mov ebx, [ebx+2*4]
.endif
invoke fopen, ebx, CStr("wb")
.if ( eax )
mov ebx, eax
invoke fwrite, outbuf, 1, outbsize, ebx
.if ( eax != outbsize )
invoke printf, CStr(<"write error [%u]",lf>), errno
.endif
invoke fclose, ebx
invoke printf, CStr(<"Done. %u bytes written",lf>), outbsize
.else
invoke printf, CStr(<"open('%s') failed [%u]",lf>), ebx, errno
.endif
invoke free, outbuf
.endif
.else
invoke printf, CStr(<"open('%s') failed [%u]",lf>), ebx, errno
.endif
xor eax,eax
ret
align 4
main endp
end
|