Functions that should be static
Francois Gouget
fgouget at free.fr
Thu Dec 18 03:09:02 CST 2008
I have attached a script that identifies functions that should be made
static (among other things). There are approximately 450 of them, there
should be pretty efw false positives, and I will look into them
eventually. But if someone beats me to it I sure won't complain <g>.
So if you do try to tackle them you are likely to find that they fall
into one of the following categories:
1) Unused debug functions.
For instance for dumping the contents of a structure to stderr.
Although these are unused we probably want to keep them. Let me know
about these and I will put them in an exception list.
2) Functions that should be exported by a spec file
It happens. Sometimes the developer implementing a function just
forgets to add it to the spec file!
3) Generated functions
This typically happens with widl: it generates a bunch of functions
for the client / server and proxy cases, but these functions may be
unused. I have special code to not warn about these, but there may
be other cases. For instance in the list below you will find a
number of yy*() functions generated by lex. Either we can tell lex
to make them static or to not generate them, or I should make
another special case. If you find some of these, let me know.
4) Assembly functions
I believe there should not be any of these in the list below.
So if you find one let me know.
5) Functions declared in a private header file but implemented and used
from a single C file.
I'm in favor of removing these functions from the private header and
making them static.
6) All the others should be pretty clear-cut.
dlls/advapi32/advapi32.dll.so: CRYPT_DESkey8to7
dlls/browseui/tests/browseui_test.exe.so: strdup_AtoW
dlls/browseui/tests/browseui_test.exe.so: TestACL_ACList_AddRef
dlls/browseui/tests/browseui_test.exe.so: TestACL_ACList_QueryInterface
dlls/browseui/tests/browseui_test.exe.so: TestACL_ACList_Release
dlls/browseui/tests/browseui_test.exe.so: TestACL_AddRef
dlls/browseui/tests/browseui_test.exe.so: TestACL_Clone
dlls/browseui/tests/browseui_test.exe.so: TestACL_Expand
dlls/browseui/tests/browseui_test.exe.so: TestACL_Next
dlls/browseui/tests/browseui_test.exe.so: TestACL_QueryInterface
dlls/browseui/tests/browseui_test.exe.so: TestACL_Release
dlls/browseui/tests/browseui_test.exe.so: TestACL_Reset
dlls/browseui/tests/browseui_test.exe.so: TestACL_Skip
dlls/cabinet/cabinet.dll.so: checksum
dlls/cabinet/cabinet.dll.so: make_decode_table
dlls/cabinet/cabinet.dll.so: QTMupdatemodel
dlls/comctl32/tests/comctl32_test.exe.so: flush_sequence
dlls/comdlg32/comdlg32.dll.so: CC_WMCommand
dlls/crypt32/crypt32.dll.so: ContextList_Empty
dlls/dbghelp/dbghelp.dll.so: hash_table_find
dlls/dbghelp/dbghelp.dll.so: hash_table_hash
dlls/dbghelp/dbghelp.dll.so: module_find_by_name
dlls/dbghelp/dbghelp.dll.so: module_get_container
dlls/dinput/dinput.dll.so: DIEnumDevicesCallbackAtoW
dlls/dmime/dmime.dll.so: DMUSIC_CreateDirectMusicobjImpl
dlls/dmime/dmime.dll.so: DMUSIC_CreateDirectMusicPatternTrackImpl
dlls/dmusic/dmusic.dll.so: DMUSIC_CreateDirectMusicBufferImpl
dlls/dmusic/dmusic.dll.so: DMUSIC_CreateDirectMusicDownloadedInstrumentImpl
dlls/dmusic/dmusic.dll.so: DMUSIC_CreateDirectMusicDownloadImpl
dlls/dnsapi/dnsapi.dll.so: dns_ns_name_pton
dlls/dplayx/dplayx.dll.so: cbDeleteGroupsElem
dlls/dplayx/dplayx.dll.so: cbDeletePlayerElem
dlls/dplayx/dplayx.dll.so: DPLAYX_DestroyLobbyApplication
dlls/dplayx/dplayx.dll.so: DPLAYX_SetLocalSession
dlls/dplayx/dplayx.dll.so: NS_GetOtherMagic
dlls/dplayx/dplayx.dll.so: NS_SetRemoteComputerAsNameServer
dlls/dsound/dsound.dll.so: DirectSoundCaptureDevice_AddRef
dlls/fusion/fusion.dll.so: assembly_get_architecture
dlls/fusion/fusion.dll.so: CompareAssemblyIdentity
dlls/fusion/fusion.dll.so: GetAssemblyIdentityFromFile
dlls/inetcomm/inetcomm.dll.so: InternetTransport_Read
dlls/iphlpapi/iphlpapi.dll.so: getInterfaceEntryByIndex
dlls/iphlpapi/iphlpapi.dll.so: getInterfacePhysicalByName
dlls/itss/itss.dll.so: chm_enumerate
dlls/jscript/jscript.dll.so: jsdisp_call
dlls/jscript/jscript.dll.so: parser_parse
dlls/mountmgr.sys/mountmgr.sys.so: DriverEntry
dlls/msacm32/msacm32.dll.so: MSACM_UnregisterLocalDriver
dlls/mshtml/mshtml.dll.so: HTMLElementCollection_Create
dlls/msi/msi.dll.so: cond_parse
dlls/msi/msi.dll.so: ControlEvent_UnSubscribeToEvent
dlls/msi/msi.dll.so: db_get_raw_stream
dlls/msi/msi.dll.so: encode_streamname
dlls/msi/msi.dll.so: find_published_source
dlls/msi/msi.dll.so: MSI_DatabaseExport
dlls/msi/msi.dll.so: MSI_DatabaseImport
dlls/msi/msi.dll.so: msi_dialog_register_class
dlls/msi/msi.dll.so: MSI_EnableUIPreview
dlls/msi/msi.dll.so: msi_id2stringA
dlls/msi/msi.dll.so: msi_id2stringW
dlls/msi/msi.dll.so: msi_load_media_info
dlls/msi/msi.dll.so: MSI_PreviewDialogW
dlls/msi/msi.dll.so: MSI_RecordDataSize
dlls/msi/msi.dll.so: MSI_RecordSetStream
dlls/msi/msi.dll.so: MSI_RecordSetStringA
dlls/msi/msi.dll.so: MSIREG_OpenInstallerFeaturesKey
dlls/msi/msi.dll.so: msi_strcmp
dlls/msi/msi.dll.so: msi_string2idA
dlls/msi/msi.dll.so: msi_ui_error
dlls/msi/msi.dll.so: msi_version_dword_to_str
dlls/msi/msi.dll.so: reduce_to_shortfilename
dlls/msi/msi.dll.so: sql_parse
dlls/msxml3/msxml3.dll.so: httprequest_Release
dlls/msxml3/msxml3.dll.so: XMLElementCollection_create
dlls/netapi32/netapi32.dll.so: NBNameCacheUpdateNBName
dlls/ole32/ole32.dll.so: IMalloc16_Constructor
dlls/qcap/qcap.dll.so: FreeMediaType
dlls/qcap/qcap.dll.so: IPinImpl_QueryInternalConnections
dlls/quartz/quartz.dll.so: MemInputPin_AddRef
dlls/quartz/quartz.dll.so: MemInputPin_GetAllocator
dlls/quartz/quartz.dll.so: MemInputPin_GetAllocatorRequirements
dlls/quartz/quartz.dll.so: MemInputPin_NotifyAllocator
dlls/quartz/quartz.dll.so: MemInputPin_QueryInterface
dlls/quartz/quartz.dll.so: MemInputPin_Receive
dlls/quartz/quartz.dll.so: MemInputPin_ReceiveCanBlock
dlls/quartz/quartz.dll.so: MemInputPin_ReceiveMultiple
dlls/quartz/quartz.dll.so: MemInputPin_Release
dlls/quartz/quartz.dll.so: OutputPin_DeliverNewSegment
dlls/riched20/riched20.dll.so: ME_ConcatString
dlls/riched20/riched20.dll.so: ME_CopyToCF2W
dlls/riched20/riched20.dll.so: ME_DestroyEditor
dlls/riched20/riched20.dll.so: ME_DITypesEqual
dlls/riched20/riched20.dll.so: ME_DrawParagraph
dlls/riched20/riched20.dll.so: ME_FindItemFwdOrHere
dlls/riched20/riched20.dll.so: ME_FindNextURLCandidate
dlls/riched20/riched20.dll.so: ME_FindRowStart
dlls/riched20/riched20.dll.so: ME_GetOptimalBuffer
dlls/riched20/riched20.dll.so: ME_GetParaFormat
dlls/riched20/riched20.dll.so: ME_GetYScrollVisible
dlls/riched20/riched20.dll.so: ME_InvalidateFromOfs
dlls/riched20/riched20.dll.so: ME_IsCandidateAnURL
dlls/riched20/riched20.dll.so: ME_LinkNotify
dlls/riched20/riched20.dll.so: ME_MakeEditor
dlls/riched20/riched20.dll.so: ME_MakeStringB
dlls/riched20/riched20.dll.so: ME_MarkForWrapping
dlls/riched20/riched20.dll.so: ME_QueueInvalidateFromCursor
dlls/riched20/riched20.dll.so: ME_Scroll
dlls/riched20/riched20.dll.so: ME_SelectByType
dlls/riched20/riched20.dll.so: ME_SetParaFormat
dlls/riched20/riched20.dll.so: ME_ToCFAny
dlls/riched20/riched20.dll.so: ME_UpdateLinkAttribute
dlls/riched20/riched20.dll.so: ME_UpdateSelection
dlls/riched20/riched20.dll.so: ME_UpdateSelectionLinkAttribute
dlls/riched20/riched20.dll.so: REComboWndProc
dlls/riched20/riched20.dll.so: REListWndProc
dlls/riched20/riched20.dll.so: RTFExpandStyle
dlls/riched20/riched20.dll.so: RTFGetClassCallback
dlls/riched20/riched20.dll.so: RTFGetDestinationCallback
dlls/riched20/riched20.dll.so: RTFGetInputName
dlls/riched20/riched20.dll.so: RTFGetOutputName
dlls/riched20/riched20.dll.so: RTFGetReadHook
dlls/riched20/riched20.dll.so: RTFGetStyle
dlls/riched20/riched20.dll.so: RTFHexToChar
dlls/riched20/riched20.dll.so: RTFPeekToken
dlls/riched20/riched20.dll.so: RTFSetClassCallback
dlls/riched20/riched20.dll.so: RTFSetInputName
dlls/riched20/riched20.dll.so: RTFSetOutputName
dlls/riched20/riched20.dll.so: RTFSetToken
dlls/riched20/riched20.dll.so: RTFUngetToken
dlls/rpcrt4/rpcrt4.dll.so: NCA2RPC_STATUS
dlls/rpcrt4/rpcrt4.dll.so: NdrByteCountPointerMemorySize
dlls/rpcrt4/rpcrt4.dll.so: NdrRangeBufferSize
dlls/rpcrt4/rpcrt4.dll.so: NdrRangeFree
dlls/rpcrt4/rpcrt4.dll.so: NdrRangeMarshall
dlls/rpcrt4/rpcrt4.dll.so: NdrRangeMemorySize
dlls/rpcrt4/rpcrt4.dll.so: RPCRT4_receive_fragment
dlls/rpcrt4/rpcrt4.dll.so: RPCRT4_SpawnConnection
dlls/rpcrt4/rpcrt4.dll.so: RPCRT4_ValidateCommonHeader
dlls/rsaenh/rsaenh.dll.so: alloc_handle_table
dlls/rsaenh/rsaenh.dll.so: mp_2expt
dlls/rsaenh/rsaenh.dll.so: mp_abs
dlls/rsaenh/rsaenh.dll.so: mp_add_d
dlls/rsaenh/rsaenh.dll.so: mp_clamp
dlls/rsaenh/rsaenh.dll.so: mp_clear
dlls/rsaenh/rsaenh.dll.so: mp_cmp_mag
dlls/rsaenh/rsaenh.dll.so: mp_cnt_lsb
dlls/rsaenh/rsaenh.dll.so: mp_div
dlls/rsaenh/rsaenh.dll.so: mp_div_2
dlls/rsaenh/rsaenh.dll.so: mp_div_2d
dlls/rsaenh/rsaenh.dll.so: mp_div_d
dlls/rsaenh/rsaenh.dll.so: mp_dr_reduce
dlls/rsaenh/rsaenh.dll.so: mp_dr_setup
dlls/rsaenh/rsaenh.dll.so: mp_exch
dlls/rsaenh/rsaenh.dll.so: mp_grow
dlls/rsaenh/rsaenh.dll.so: mp_init
dlls/rsaenh/rsaenh.dll.so: mp_init_size
dlls/rsaenh/rsaenh.dll.so: mp_lshd
dlls/rsaenh/rsaenh.dll.so: mp_mod_2d
dlls/rsaenh/rsaenh.dll.so: mp_mod_d
dlls/rsaenh/rsaenh.dll.so: mp_montgomery_calc_normalization
dlls/rsaenh/rsaenh.dll.so: mp_montgomery_reduce
dlls/rsaenh/rsaenh.dll.so: mp_montgomery_setup
dlls/rsaenh/rsaenh.dll.so: mp_mul_2
dlls/rsaenh/rsaenh.dll.so: mp_mul_2d
dlls/rsaenh/rsaenh.dll.so: mp_mul_d
dlls/rsaenh/rsaenh.dll.so: mp_prime_is_divisible
dlls/rsaenh/rsaenh.dll.so: mp_prime_is_prime
dlls/rsaenh/rsaenh.dll.so: mp_prime_miller_rabin
dlls/rsaenh/rsaenh.dll.so: mp_reduce
dlls/rsaenh/rsaenh.dll.so: mp_reduce_2k
dlls/rsaenh/rsaenh.dll.so: mp_reduce_2k_setup
dlls/rsaenh/rsaenh.dll.so: mp_reduce_setup
dlls/rsaenh/rsaenh.dll.so: mp_rshd
dlls/rsaenh/rsaenh.dll.so: mp_set
dlls/rsaenh/rsaenh.dll.so: mp_signed_bin_size
dlls/rsaenh/rsaenh.dll.so: mp_sqr
dlls/rsaenh/rsaenh.dll.so: mp_sqrmod
dlls/rsaenh/rsaenh.dll.so: mp_zero
dlls/rsaenh/rsaenh.dll.so: release_handle_table
dlls/sane.ds/sane.ds.so: SANE_AutomaticCaptureDirectory
dlls/sane.ds/sane.ds.so: SANE_FileSystemCopy
dlls/sane.ds/sane.ds.so: SANE_PendingXfersStopFeeder
dlls/sane.ds/sane.ds.so: SANE_SetupFileXfer2Get
dlls/sane.ds/sane.ds.so: SANE_SetupFileXfer2GetDefault
dlls/sane.ds/sane.ds.so: SANE_SetupFileXfer2Reset
dlls/sane.ds/sane.ds.so: SANE_SetupFileXfer2Set
dlls/secur32/secur32.dll.so: SECUR32_initNegotiateSP
dlls/secur32/secur32.dll.so: SECUR32_strdupW
dlls/setupapi/setupapi.dll.so: PARSER_string_substW
dlls/setupapi/setupapi.dll.so: VcpEnumFiles
dlls/setupapi/setupapi.dll.so: VcpFlush16
dlls/setupapi/setupapi.dll.so: vsmStringCompare16
dlls/setupapi/setupapi.dll.so: vsmStringFind16
dlls/shell32/shell32.dll.so: HCR_GetDefaultIconFromGUIDW
dlls/shell32/shell32.dll.so: ILGetDisplayNameExA
dlls/shell32/shell32.dll.so: _ILGetSTextPointer
dlls/shell32/shell32.dll.so: _ILGetTextPointerW
dlls/shell32/shell32.dll.so: RenderFILECONTENTS
dlls/shell32/shell32.dll.so: RenderFILEDESCRIPTOR
dlls/shell32/shell32.dll.so: RenderPREFEREDDROPEFFECT
dlls/shell32/shell32.dll.so: RenderSHELLIDLISTOFFSET
dlls/shell32/shell32.dll.so: SHILCreateFromPathA
dlls/shell32/shell32.dll.so: TRASH_DisposeElement
dlls/shell32/shell32.dll.so: XDG_GetPath
dlls/user32/user32.dll.so: EditWndProcW
dlls/user32/user32.dll.so: LookupIconIdFromDirectory16
dlls/uxtheme/uxtheme.dll.so: UXINI_ResetINI
dlls/w32skrnl/w32skrnl.dll.so: _GetThunkBuff
dlls/winealsa.drv/winealsa.drv.so: ALSA_PeekRingMessage
dlls/winealsa.drv/winealsa.drv.so: wodSetVolume
dlls/winedos/winedos.dll.so: DOSDEV_Console
dlls/winedos/winedos.dll.so: DOSDEV_FindCharDevice
dlls/winedos/winedos.dll.so: DOSDEV_IoctlRead
dlls/winedos/winedos.dll.so: DOSDEV_IoctlWrite
dlls/winedos/winedos.dll.so: DOSDEV_Peek
dlls/winedos/winedos.dll.so: DOSDEV_Read
dlls/winedos/winedos.dll.so: DOSDEV_Write
dlls/winedos/winedos.dll.so: DOSVM_AllocCodeUMB
dlls/winedos/winedos.dll.so: DOSVM_AllocUMB
dlls/winedos/winedos.dll.so: DPMI_FreeInternalRMCB
dlls/winedos/winedos.dll.so: VGA_SetQuadPalette
dlls/winedos/winedos.dll.so: VGA_SetTextAttribute
dlls/wineps.drv/wineps.drv.so: PSDRV_CmpColor
dlls/wineps.drv/wineps.drv.so: PSDRV_WriteArrayGet
dlls/wineps.drv/wineps.drv.so: PSDRV_WriteInitClip
dlls/wineps.drv/wineps.drv.so: PSDRV_WriteRRectangle
dlls/winex11.drv/winex11.drv.so: X11DRV_get_client_window
dlls/winex11.drv/winex11.drv.so: X11DRV_SetupGCForPen
dlls/winex11.drv/winex11.drv.so: X11DRV_window_to_X_rect
dlls/winex11.drv/winex11.drv.so: X11DRV_XF86VM_SetExclusiveMode
dlls/winex11.drv/winex11.drv.so: X11DRV_XRandR_Cleanup
dlls/winhttp/winhttp.dll.so: netconn_set_timeout
dlls/wininet/wininet.dll.so: HTTP_FinishedReading
dlls/wininet/wininet.dll.so: HTTP_GetHeader
dlls/wininet/wininet.dll.so: HTTP_HttpOpenRequestW
dlls/wininet/wininet.dll.so: HTTP_HttpSendRequestW
dlls/winmm/winmm.dll.so: MCI_DefYieldProc
dlls/winmm/winmm.dll.so: MCI_GetDriverFromString
dlls/winmm/winmm.dll.so: MCI_SendCommandFrom16
dlls/winmm/winmm.dll.so: MCI_SendCommandFrom32
dlls/winmm/winmm.dll.so: MCI_WriteString
dlls/wintrust/wintrust.dll.so: CRYPT_AsnEncodeInt
dlls/wintrust/wintrust.dll.so: WINTRUST_ReAlloc
dlls/wnaspi32/wnaspi32.dll.so: ASPI_SendASPICommand
dlls/wnaspi32/wnaspi32.dll.so: SCSI_GetDeviceName
dlls/wuapi/wuapi.dll.so: AutomaticUpdates_create
programs/cmd/cmd.exe.so: handleExpansion
programs/cmd/cmd.exe.so: WCMD_addCommand
programs/cmd/cmd.exe.so: WCMD_ask_confirm
programs/cmd/cmd.exe.so: WCMD_dir_sort
programs/cmd/cmd.exe.so: WCMD_filesize64
programs/cmd/cmd.exe.so: WCMD_opt_s_strip_quotes
programs/cmd/cmd.exe.so: WCMD_parse
programs/cmd/cmd.exe.so: WCMD_show_prompt
programs/cmd/cmd.exe.so: WCMD_strrev
programs/cmd/cmd.exe.so: WCMD_strtrim_trailing_spaces
programs/oleview/oleview.exe.so: AddToStrW
programs/oleview/oleview.exe.so: AddToTLDataStrW
programs/oleview/oleview.exe.so: AddToTLDataStrWithTabsW
programs/oleview/oleview.exe.so: CreateInstOnProc
programs/oleview/oleview.exe.so: DetailsProc
programs/oleview/oleview.exe.so: InterfaceViewerProc
programs/oleview/oleview.exe.so: PaneProc
programs/oleview/oleview.exe.so: SysConfProc
programs/oleview/oleview.exe.so: TreeProc
programs/oleview/oleview.exe.so: TypeLibProc
programs/oleview/oleview.exe.so: WndProc
programs/progman/progman.exe.so: DIALOG_Symbol
programs/regedit/regedit.exe.so: GetMultiByteStringN
programs/regedit/regedit.exe.so: GetRootKeyName
programs/regedit/regedit.exe.so: GetWideStringN
programs/regedit/regedit.exe.so: HexEdit_Unregister
programs/regedit/regedit.exe.so: processRegLinesA
programs/regedit/regedit.exe.so: processRegLinesW
programs/taskmgr/taskmgr.exe.so: Draw3dRect
programs/taskmgr/taskmgr.exe.so: Draw3dRect2
programs/taskmgr/taskmgr.exe.so: FillSolidRect2
programs/taskmgr/taskmgr.exe.so: GraphCtrl_DrawPoint
programs/taskmgr/taskmgr.exe.so: GraphCtrl_InvalidateCtrl
programs/taskmgr/taskmgr.exe.so: GraphCtrl_Paint
programs/taskmgr/taskmgr.exe.so: GraphCtrl_Resize
programs/taskmgr/taskmgr.exe.so: TrayIcon_GetProcessorUsageIcon
programs/taskmgr/taskmgr.exe.so: UpdateApplicationListControlViewSetting
programs/view/view.exe.so: FileIsPlaceable
programs/view/view.exe.so: GetPlaceableMetaFile
programs/winecfg/winecfg.exe.so: enumerate_valuesW
programs/wineconsole/wineconsole.exe.so: WCUSER_AreFontsEqual
programs/wineconsole/wineconsole.exe.so: WINECON_FetchCells
programs/wineconsole/wineconsole.exe.so: WINECON_GetHistoryMode
programs/wineconsole/wineconsole.exe.so: WINECON_SetHistoryMode
programs/wineconsole/wineconsole.exe.so: WINECON_SetHistorySize
programs/winedbg/winedbg.exe.so: be_cpu_build_addr
programs/winedbg/winedbg.exe.so: be_cpu_linearize
programs/winedbg/winedbg.exe.so: dbg_alloc
programs/winedbg/winedbg.exe.so: dbg__create_buffer
programs/winedbg/winedbg.exe.so: dbg__delete_buffer
programs/winedbg/winedbg.exe.so: dbg__flush_buffer
programs/winedbg/winedbg.exe.so: dbg_free
programs/winedbg/winedbg.exe.so: dbg_get_debug
programs/winedbg/winedbg.exe.so: dbg_get_in
programs/winedbg/winedbg.exe.so: dbg_get_leng
programs/winedbg/winedbg.exe.so: dbg_get_lineno
programs/winedbg/winedbg.exe.so: dbg_get_out
programs/winedbg/winedbg.exe.so: dbg_get_text
programs/winedbg/winedbg.exe.so: dbg_lex_destroy
programs/winedbg/winedbg.exe.so: dbg_outputA
programs/winedbg/winedbg.exe.so: dbg_parse
programs/winedbg/winedbg.exe.so: dbg_pop_buffer_state
programs/winedbg/winedbg.exe.so: dbg_push_buffer_state
programs/winedbg/winedbg.exe.so: dbg_realloc
programs/winedbg/winedbg.exe.so: dbg_restart
programs/winedbg/winedbg.exe.so: dbg__scan_buffer
programs/winedbg/winedbg.exe.so: dbg__scan_bytes
programs/winedbg/winedbg.exe.so: dbg__scan_string
programs/winedbg/winedbg.exe.so: dbg_set_debug
programs/winedbg/winedbg.exe.so: dbg_set_in
programs/winedbg/winedbg.exe.so: dbg_set_lineno
programs/winedbg/winedbg.exe.so: dbg_set_out
programs/winedbg/winedbg.exe.so: dbg__switch_to_buffer
programs/winedbg/winedbg.exe.so: dbg_wrap
programs/winedbg/winedbg.exe.so: expr_alloc_uconstant
programs/winedbg/winedbg.exe.so: lexeme_alloc
programs/winedbg/winedbg.exe.so: parser
programs/winedbg/winedbg.exe.so: validate_file
programs/winemine/winemine.exe.so: AboutDlgProc
programs/winemine/winemine.exe.so: AddFlag
programs/winemine/winemine.exe.so: CompleteBox
programs/winemine/winemine.exe.so: CompleteBoxes
programs/winemine/winemine.exe.so: CreateBoard
programs/winemine/winemine.exe.so: DestroyBoard
programs/winemine/winemine.exe.so: DrawBoard
programs/winemine/winemine.exe.so: DrawFace
programs/winemine/winemine.exe.so: DrawLeds
programs/winemine/winemine.exe.so: DrawMine
programs/winemine/winemine.exe.so: DrawMines
programs/winemine/winemine.exe.so: InitBoard
programs/winemine/winemine.exe.so: LoadBoard
programs/winemine/winemine.exe.so: MainProc
programs/winemine/winemine.exe.so: PlaceMines
programs/winemine/winemine.exe.so: PressBox
programs/winemine/winemine.exe.so: PressBoxes
programs/winemine/winemine.exe.so: SaveBoard
programs/winemine/winemine.exe.so: SetDifficulty
programs/winemine/winemine.exe.so: TestBoard
programs/winemine/winemine.exe.so: TestFace
programs/winemine/winemine.exe.so: TestMines
programs/winemine/winemine.exe.so: UnpressBox
programs/winemine/winemine.exe.so: UnpressBoxes
programs/winhlp32/winhlp32.exe.so: HLPFILE_BPTreeSearch
programs/winhlp32/winhlp32.exe.so: HLPFILE_Contents
programs/winhlp32/winhlp32.exe.so: HLPFILE_HalfPointsToTwips
programs/winhlp32/winhlp32.exe.so: MACRO_AddAccelerator
programs/winhlp32/winhlp32.exe.so: MACRO_ALink
programs/winhlp32/winhlp32.exe.so: MACRO_AppendItem
programs/winhlp32/winhlp32.exe.so: MACRO_Back
programs/winhlp32/winhlp32.exe.so: MACRO_BackFlush
programs/winhlp32/winhlp32.exe.so: MACRO_BookmarkMore
programs/winhlp32/winhlp32.exe.so: MACRO_BrowseButtons
programs/winhlp32/winhlp32.exe.so: MACRO_ChangeButtonBinding
programs/winhlp32/winhlp32.exe.so: MACRO_ChangeEnable
programs/winhlp32/winhlp32.exe.so: MACRO_ChangeItemBinding
programs/winhlp32/winhlp32.exe.so: MACRO_CheckItem
programs/winhlp32/winhlp32.exe.so: MACRO_CloseSecondarys
programs/winhlp32/winhlp32.exe.so: MACRO_CloseWindow
programs/winhlp32/winhlp32.exe.so: MACRO_Compare
programs/winhlp32/winhlp32.exe.so: MACRO_Contents
programs/winhlp32/winhlp32.exe.so: MACRO_ControlPanel
programs/winhlp32/winhlp32.exe.so: MACRO_CopyTopic
programs/winhlp32/winhlp32.exe.so: MACRO_DeleteItem
programs/winhlp32/winhlp32.exe.so: MACRO_DeleteMark
programs/winhlp32/winhlp32.exe.so: MACRO_DestroyButton
programs/winhlp32/winhlp32.exe.so: MACRO_DisableItem
programs/winhlp32/winhlp32.exe.so: MACRO_EnableButton
programs/winhlp32/winhlp32.exe.so: MACRO_EnableItem
programs/winhlp32/winhlp32.exe.so: MACRO_EndMPrint
programs/winhlp32/winhlp32.exe.so: MACRO_ExecFile
programs/winhlp32/winhlp32.exe.so: MACRO_ExecProgram
programs/winhlp32/winhlp32.exe.so: MACRO_ExtAbleItem
programs/winhlp32/winhlp32.exe.so: MACRO_ExtInsertItem
programs/winhlp32/winhlp32.exe.so: MACRO_ExtInsertMenu
programs/winhlp32/winhlp32.exe.so: MACRO_FileExist
programs/winhlp32/winhlp32.exe.so: MACRO_Find
programs/winhlp32/winhlp32.exe.so: MACRO_Finder
programs/winhlp32/winhlp32.exe.so: MACRO_FloatingMenu
programs/winhlp32/winhlp32.exe.so: MACRO_Flush
programs/winhlp32/winhlp32.exe.so: MACRO_FocusWindow
programs/winhlp32/winhlp32.exe.so: MACRO_Generate
programs/winhlp32/winhlp32.exe.so: MACRO_GotoMark
programs/winhlp32/winhlp32.exe.so: MACRO_IfThen
programs/winhlp32/winhlp32.exe.so: MACRO_IfThenElse
programs/winhlp32/winhlp32.exe.so: MACRO_InitMPrint
programs/winhlp32/winhlp32.exe.so: MACRO_InsertItem
programs/winhlp32/winhlp32.exe.so: MACRO_InsertMenu
programs/winhlp32/winhlp32.exe.so: MACRO_IsBook
programs/winhlp32/winhlp32.exe.so: MACRO_IsMark
programs/winhlp32/winhlp32.exe.so: MACRO_IsNotMark
programs/winhlp32/winhlp32.exe.so: MACRO_JumpHelpOn
programs/winhlp32/winhlp32.exe.so: MACRO_JumpID
programs/winhlp32/winhlp32.exe.so: MACRO_JumpKeyword
programs/winhlp32/winhlp32.exe.so: MACRO_KLink
programs/winhlp32/winhlp32.exe.so: MACRO_Menu
programs/winhlp32/winhlp32.exe.so: MACRO_MPrintHash
programs/winhlp32/winhlp32.exe.so: MACRO_MPrintID
programs/winhlp32/winhlp32.exe.so: MACRO_Next
programs/winhlp32/winhlp32.exe.so: MACRO_NoShow
programs/winhlp32/winhlp32.exe.so: MACRO_PopupHash
programs/winhlp32/winhlp32.exe.so: MACRO_PopupId
programs/winhlp32/winhlp32.exe.so: MACRO_PositionWindow
programs/winhlp32/winhlp32.exe.so: MACRO_Prev
programs/winhlp32/winhlp32.exe.so: MACRO_RegisterRoutine
programs/winhlp32/winhlp32.exe.so: MACRO_RemoveAccelerator
programs/winhlp32/winhlp32.exe.so: MACRO_ResetMenu
programs/winhlp32/winhlp32.exe.so: MACRO_SaveMark
programs/winhlp32/winhlp32.exe.so: MACRO_Search
programs/winhlp32/winhlp32.exe.so: MACRO_SetHelpOnFile
programs/winhlp32/winhlp32.exe.so: MACRO_SetPopupColor
programs/winhlp32/winhlp32.exe.so: MACRO_ShellExecute
programs/winhlp32/winhlp32.exe.so: MACRO_ShortCut
programs/winhlp32/winhlp32.exe.so: MACRO_TCard
programs/winhlp32/winhlp32.exe.so: MACRO_Test
programs/winhlp32/winhlp32.exe.so: MACRO_TestALink
programs/winhlp32/winhlp32.exe.so: MACRO_TestKLink
programs/winhlp32/winhlp32.exe.so: MACRO_UncheckItem
programs/winhlp32/winhlp32.exe.so: MACRO_UpdateWindow
programs/winhlp32/winhlp32.exe.so: WINHELP_IndexDlgProc
programs/winhlp32/winhlp32.exe.so: WINHELP_MessageBoxIDS_s
programs/winhlp32/winhlp32.exe.so: WINHELP_SearchDlgProc
programs/winhlp32/winhlp32.exe.so: yyalloc
programs/winhlp32/winhlp32.exe.so: yy_create_buffer
programs/winhlp32/winhlp32.exe.so: yy_delete_buffer
programs/winhlp32/winhlp32.exe.so: yy_flush_buffer
programs/winhlp32/winhlp32.exe.so: yyfree
programs/winhlp32/winhlp32.exe.so: yyget_debug
programs/winhlp32/winhlp32.exe.so: yyget_in
programs/winhlp32/winhlp32.exe.so: yyget_leng
programs/winhlp32/winhlp32.exe.so: yyget_lineno
programs/winhlp32/winhlp32.exe.so: yyget_out
programs/winhlp32/winhlp32.exe.so: yyget_text
programs/winhlp32/winhlp32.exe.so: yylex
programs/winhlp32/winhlp32.exe.so: yylex_destroy
programs/winhlp32/winhlp32.exe.so: yypop_buffer_state
programs/winhlp32/winhlp32.exe.so: yypush_buffer_state
programs/winhlp32/winhlp32.exe.so: yyrealloc
programs/winhlp32/winhlp32.exe.so: yyrestart
programs/winhlp32/winhlp32.exe.so: yy_scan_buffer
programs/winhlp32/winhlp32.exe.so: yy_scan_bytes
programs/winhlp32/winhlp32.exe.so: yy_scan_string
programs/winhlp32/winhlp32.exe.so: yyset_debug
programs/winhlp32/winhlp32.exe.so: yyset_in
programs/winhlp32/winhlp32.exe.so: yyset_lineno
programs/winhlp32/winhlp32.exe.so: yyset_out
programs/winhlp32/winhlp32.exe.so: yy_switch_to_buffer
programs/winhlp32/winhlp32.exe.so: yywrap
--
Francois Gouget <fgouget at free.fr> http://fgouget.free.fr/
War doesn't determine who's right. War determines who's left.
-------------- next part --------------
#!/usr/bin/perl -w
use strict;
my $name0=$0;
$name0 =~ s%^.*/%%;
my $IDENTIFIER="[a-zA-Z_][a-zA-Z0-9_]*";
my $MANGLEDIDENT="[a-zA-Z0-9_?@\$]+";
my $SPECIDENT="$IDENTIFIER(?:\.$MANGLEDIDENT)*";
my $SPECOPT="-[a-zA-Z0-9_=,]+\\s+";
### List of linefeed issues to ignore
my %lf_blacklist=(
"dlls/comctl32/rebar.c" => {"\"band # \%u: xHeader=\%u\"" => 1},
"dlls/d3d8/device.c" => {"\"Searching for declaration for fvf \%08x... \"" => 1},
"dlls/d3d9/device.c" => {"\"Searching for declaration for fvf \%08x... \"" => 1},
"dlls/ddraw/ddraw.c" => {"\"Searching for declaration for fvf \%08x... \"" => 1},
"dlls/ddraw/utils.c" => {"\"\%s \"" => 1,
"\" R \"" => 1,
"\" - \"" => 1},
"dlls/dinput/effect_linuxinput.c" => {"\"\%[ds] \"" => 1},
"dlls/dinput/mouse.c" => {"\"\\(X: \%d Y: \%d Z: \%d\"" => 1},
"dlls/dsound/dsound.c" => {"\"\%s \",flags\\[i\\]\\.name" => 1},
"dlls/gdi32/freetype.c" => {"\"\\\\t\%s\\\\t\%08x\"" => 1},
"dlls/ntdll/loader.c" => {"\"No implementation for \%s\\.%[ds]\"" => 1},
"dlls/ntdll/rtl.c" => {"\"\%s\%x: \%s\"" => 1},
"dlls/ntdll/time.c" => {"\"starting date isdst \%d, \%s\"" => 1,
"\"year_start: \%s\"" => 1,
"\"std: \%s\"" => 1,
"\"dlt gmtime: \%s\"" => 1,
"\"std gmtime: \%s\"" => 1},
"dlls/ntdll/virtual.c" => {"\"View: \%p - \%p\"" => 1},
"dlls/odbc32/proxyodbc.c" => {"\"returns: \%d \\\\t\"" => 1},
"dlls/ole32/marshal.c" => {"\" MSHLFLAGS_TABLESTRONG\"" => 1},
"dlls/oleaut32/tmarshal.c" => {"\"*\"" => 1},
"dlls/oleaut32/typelib.c" => {"\"\%p->\\{\%s\%s\"" => 1},
"dlls/oleaut32/varformat.c" => {"\"\%s0x%02x\"" => 1},
"dlls/quartz/dsoundrender.c" => {"\"%02x \"" => 1},
"dlls/quartz/videorenderer.c" => {"\"%02x \"" => 1},
"dlls/rpcrt4/ndr_marshall.c" => {"\" RPC_FC_P_ALLOCALLNODES\"" => 1},
"dlls/rpcrt4/ndr_stubless.c" => {"\" MustSize\"" => 1,
"\" ServerMustSize\"" => 1},
"dlls/rpcrt4/rpc_binding.c" => {"\"SecurityQos { Version=\%ld, Capabilties=0x\%lx, IdentityTracking=\%ld, ImpersonationLevel=\%ld\"" => 1},
"dlls/secur32/dispatcher.c" => {"\"\%s \"" => 1},
"dlls/secur32/schannel.c" => {"\"<\%d> \%s\"" => 1},
"dlls/setupapi/parser.c" => {"\"\%p/\%p/\%d/\%d index \%d returning\"" => 1},
"dlls/snmpapi/main.c" => {"\"\%u\"" => 1,
"\"String \"" => 1,
"\"IpAddress \"" => 1,
"\"Bits \"" => 1,
"\"Opaque \"" => 1,
"\"ObjectID \"" => 1},
"dlls/user32/listbox.c" => {"\\[\%p\\]: settabstops \"" => 1},
"dlls/user32/menu.c" => {"\"\%s\%s\"" => 1,
"\"\%s \"" => 1},
"dlls/user32/painting.c" => {"\"\%p region \%p box \%s \"" => 1},
"dlls/user32/scroll.c" => {"\"hwnd=\%p bar=\%d\"" => 1},
"dlls/user32/tests/msg.c" => {"\"\%p after \%p, x \%d, y \%d, cx \%d, cy \%d flags \%08x \"" => 1},
"dlls/usp10/usp10.c" => {"\"New_Script=\%d, eScript=\%d \"" => 1,
"\"Item \%d, Glyphs \%d \"" => 1},
"dlls/version/info.c" => {"\"filetype=APP\"" => 1},
"dlls/winecoreaudio.drv/midi.c" => {"\"\%02X \"" => 1},
"dlls/wined3d/baseshader.c" => {"\"GL HW \\(\%u, \%u\\) : \%s\"" => 1,
"\"dcl\"" => 1,
"\"-\"" => 1,
"\"_d8\"" => 1,
"\"def c\%u = \%f, \%f, \%f, \%f\"" => 1,
"\"%s\"" => 1},
"dlls/wined3d/vertexbuffer.c" => {"\"[[]\%d[]]\"" => 1},
"dlls/winex11.drv/dib.c" => {"\"%04x/%04lx \"" => 1},
"dlls/winex11.drv/opengl.c" => {"\"\\('\%s'\\):\%\\*s\"" => 1,
"\"\\*\"" => 1},
"dlls/wininet/internet.c" => {"\" %s\"" => 1},
);
### List of stdcall equivalents
my @stdcall_seeds=qw(__stdcall);
my (%macros, $stdcall_re);
### List of 'static stdcall' functions to ignore
my %static_ignore=(
"dlls/winedos/interrupts.c" => {DOSVM_Int20Handler => 1,
DOSVM_Int5cHandler => 1},
"dlls/winmm/message16.c" => {MMDRV_Aux_Callback => 1,
MMDRV_Mixer_Callback => 1,
MMDRV_MidiIn_Callback => 1,
MMDRV_MidiOut_Callback => 1,
MMDRV_WaveIn_Callback => 1,
MMDRV_WaveOut_Callback => 1},
"programs/cmdlgtst/cmdlgtst.c" => {dummyfnHook => 1},
);
### List of pointers for the NULL cast checker
my (%typedefs, %pointers);
### List of macros that are equal to 0
my %zeroes=(NULL => 1);
### List of undef-ed macros
my %undefs;
### List of exported functions to ignore
my %export_ignore=(
"dlls/dpnet" => {debugstr_SP => 1},
"dlls/kernel32" => {NE_DumpModule => 1,
NE_WalkModules => 1,
debug_handles => 1},
"dlls/ntdll" => {__wine_process_init => 1,
__wine_spec_unimplemented_stub => 1},
"dlls/ole32" => {STORAGE_dump_pps_entry => 1},
"dlls/riched20" => {ME_DumpParaStyleToBuf => 1,
ME_DumpStyle => 1},
"dlls/wined3d" => {debug_fixup_channel_source => 1,
debug_yuv_fixup => 1},
"dlls/wineoss.drv" => {seqbuf_dump => 1},
);
### List of functions implemented or referenced from assembly code,
### sorted by directory
my %asm_functions;
### List of standard sublanguages
my %standard_sublangs=(
SUBLANG_NEUTRAL => 1,
SUBLANG_DEFAULT => 1,
SUBLANG_SYS_DEFAULT => 1,
SUBLANG_CUSTOM_DEFAULT => 1,
SUBLANG_CUSTOM_UNSPECIFIED => 1,
SUBLANG_UI_CUSTOM_DEFAULT => 1
);
### Lists of the languages default sublang and of those that have many sub
### languages
my (%lang_default, %lang_manysubs);
### List of languages known to have translations for non-default sub languages
my %lang_anysub=(
LANG_ENGLISH => 1,
LANG_PORTUGUESE => 1
);
my $verbose;
sub verbose(@)
{
return print STDERR @_ if ($verbose);
}
my $debug;
sub debug(@)
{
return print STDERR @_ if ($debug);
}
sub err(@)
{
print STDERR "$name0:error: ", @_;
}
sub dirname($)
{
my ($path)=@_;
return "" if ($path !~ s!/[^/]+$!!);
return $path;
}
my @file;
my $l;
my @chars;
my $len;
my $c;
sub skip_bracket();
sub skip_parent();
sub skip_string();
sub setup_line($)
{
return 0 if ($l >= @file);
$c=$_[0];
$len=length($file[$l]);
@chars=split //, $file[$l];
debug("$l,$c: $file[$l]");
return 1;
}
sub set_position($$)
{
return 0 if ($l >= @file);
$c=$_[0];
$l=$_[1];
$len=length($file[$l]);
@chars=split //, $file[$l];
debug("$l,$c: $file[$l]");
return 1;
}
sub skip_bracket()
{
while (1)
{
while ($c < $len)
{
debug("skip_bracket: $c -> '$chars[$c]'\n");
if ($chars[$c] eq "]")
{
debug("skip_bracket returns 1\n");
return 1;
}
elsif ($chars[$c] eq "\"")
{
$c++;
skip_string();
}
elsif ($chars[$c] eq "(")
{
$c++;
skip_parent();
}
elsif ($chars[$c] eq "[")
{
$c++;
skip_bracket();
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub skip_parent()
{
while (1)
{
while ($c < $len)
{
debug("skip_parent: $c -> '$chars[$c]'\n");
if ($chars[$c] eq ")")
{
debug("skip_parent returns 1\n");
return 1;
}
elsif ($chars[$c] eq "\"")
{
$c++;
skip_string();
}
elsif ($chars[$c] eq "(")
{
$c++;
skip_parent();
}
elsif ($chars[$c] eq "[")
{
$c++;
skip_bracket();
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub skip_string()
{
my $backslash;
while (1)
{
while ($c < $len)
{
debug("skip_string: $c -> '$chars[$c]'\n");
if ($chars[$c] eq "\"")
{
if (!$backslash)
{
debug("skip_string returns 1\n");
return 1;
}
$backslash=undef;
}
elsif ($chars[$c] eq "\\")
{
$backslash=($backslash?undef:1);
}
else
{
$backslash=undef;
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub skip_comment()
{
my $star;
while (1)
{
while ($c < $len)
{
debug("skip_comment: $c -> '$chars[$c]'\n");
if ($chars[$c] eq "*")
{
$star=1;
}
elsif ($chars[$c] eq "/")
{
return 1 if ($star);
}
else
{
$star=0;
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub skip_arg()
{
while (1)
{
while ($c < $len)
{
debug("skip_arg: $c -> '$chars[$c]'\n");
if ($chars[$c] eq ",")
{
debug("skip_arg returns 1\n");
return 1;
}
elsif ($chars[$c] eq "\"")
{
$c++;
skip_string();
}
elsif ($chars[$c] eq "(")
{
$c++;
skip_parent();
}
elsif ($chars[$c] eq "[")
{
$c++;
skip_bracket();
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub get_quote()
{
while (1)
{
while ($c < $len)
{
debug("get_quote: $c -> '$chars[$c]'\n");
if ($chars[$c] eq "\"")
{
debug("get_quote returns 1\n");
return 1;
}
elsif ($chars[$c] eq "\\")
{
return 0 if ($c+1==$len or $chars[$c+1] ne "\n");
}
elsif ($chars[$c] eq "/" and $c+1 < $len and $chars[$c+1] eq "*")
{
return 0 if (!skip_comment());
}
elsif ($chars[$c] !~ /(\s|\n)/)
{
return 0;
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
sub get_comma()
{
while (1)
{
while ($c < $len)
{
debug("get_comma: $c -> '$chars[$c]'\n");
if ($chars[$c] eq ",")
{
debug("get_comma returns 1\n");
return 1;
}
elsif ($chars[$c] eq "\\")
{
return 0 if ($c+1==$len or $chars[$c+1] ne "\n");
}
elsif ($chars[$c] !~ /(\s|\n|[a-zA-Z0-9\#])/)
{
return 0;
}
$c++;
}
$l++;
return 0 if (!setup_line(0));
}
return 0;
}
my $lf_set_ignore;
sub fix_lf($$$$)
{
my ($needs_lf, $heuristics, $arg, $pos)=@_;
setup_line($pos);
verbose("processing:",$l+1," ",substr($file[$l], $pos));
# Locate the format string
for (my $i=1; $i < $arg; $i++)
{
return undef if (!skip_arg());
$c++;
}
return undef if (!get_quote());
# See if this is a string of the form "xxx" #var "yyy"
my ($quote_c, $quote_l);
while ($c < $len)
{
last if ($chars[$c] ne "\"");
$c++;
return "" if (!skip_string());
$quote_c=$c;
$quote_l=$l;
$c++;
last if (get_comma());
}
set_position($quote_c, $quote_l);
# Check and modify
if ($needs_lf)
{
if ($c >= 2 and ($chars[$c-2] ne "\\" or $chars[$c-1] ne "n"))
{
my $start=substr($file[$l], 0, $c);
verbose(" start=[$start]\n");
if ($start =~ /\\r$/ or $start =~ /\"\s*$/)
{
return $file[$l];
}
elsif ($heuristics and
($start =~ /(?:->|[=:,|{([])\s*$/ or
# For the dm* dlls
$start =~ /\": \%s chunk \(size = (?:0x%04x|0x%08X|\%d)\)$/ or
$start =~ /\": (?:LIST|RIFF) chunk of type \%s$/
))
{
verbose(" matched=[$&]\n");
$lf_set_ignore=1;
return $file[$l];
}
else
{
$start=~s/\s*$/\\n/;
return $start . substr($file[$l], $c);
}
}
elsif ($c >= 3 and $chars[$c-3] eq " " and
$chars[$c-2] eq "\\" and $chars[$c-1] eq "n")
{
my $space=$c-3;
while ($space > 0 and $chars[$space] eq " ")
{
$space--;
}
return substr($file[$l], 0, $space+1) . substr($file[$l], $c-2);
}
}
else
{
my $cut=$c;
if ($cut >= 2 and $chars[$cut-2] eq "\\" and $chars[$cut-1] eq "n")
{
$cut-=2;
}
while ($cut > 0)
{
$cut--;
last if ($chars[$cut] ne " ");
}
return substr($file[$l], 0, $cut+1) . substr($file[$l], $c);
}
return $file[$l];
}
sub collect($$)
{
my ($rootdir, $filename) = @_;
debug("***** Processing $filename\n");
if (open(my $fh, "<", "$rootdir$filename"))
{
my $dir=dirname($filename);
while (my $line=<$fh>)
{
if ($line =~ /^\s*#\s*define\s+($IDENTIFIER)\s+(0(?:x0+)?L?|\(\s*0(?:x0+)?L?\s*\))\s*(\/\*.*)?$/)
{
debug("zero $1\n");
$macros{$1}=$2;
$zeroes{$1}=1;
}
elsif ($line =~ /^\s*#\s*define\s+($IDENTIFIER)\s+([0-9]+L?|0x[0-9a-fA-F]+L?|\(\s*(?:[0-9]+L?|0x[0-9a-fA-F]+L?)\s*\))\s*(\/\*.*)?$/)
{
debug("macro $1=$2\n");
$macros{$1}=$2;
}
elsif ($line =~ /^\s*#\s*define\s+($IDENTIFIER)\s+($IDENTIFIER)\s*(\/\*.*)?$/)
{
debug("macro $1=$2\n");
$macros{$1}=$2;
}
elsif ($line =~ /^\s*typedef\s+($IDENTIFIER)\s+($IDENTIFIER)\s*[;,]/)
{
debug("typedef $1 $2\n");
$typedefs{$2}=$1;
}
elsif ($line =~ /^\s*typedef\s+[^;,]*\*\s*($IDENTIFIER)\s*[;,]/)
{
debug("pointer $1: $line");
$pointers{$1}=1;
}
elsif ($line =~ /^\s*DECLARE_HANDLE\(($IDENTIFIER)\)\s*;/)
{
debug("handle $1\n");
$pointers{$1}=1;
}
elsif ($line =~ /^\s*#\s*undef\s+($IDENTIFIER)\s*(\/\*.*)?$/ and
$1 ne "YYERROR_VERBOSE")
{
debug("undef $1\n");
$undefs{$1}=1;
}
elsif ($line =~ /^\s*__ASM_GLOBAL_FUNC\s*\(\s*($IDENTIFIER)\s*,/)
{
my $function=$1;
$asm_functions{$dir}->{$function}=1;
}
elsif ($line =~ /^\s*DEFINE_REGS_ENTRYPOINT\s*\(\s*($IDENTIFIER)\s*,/)
{
my $function=$1;
$asm_functions{$dir}->{$function}=1;
$asm_functions{$dir}->{"__regs_$function"}=1;
}
elsif ($line =~ /^\s*DEFINE_(?:FASTCALL[12]|SETJMP)_ENTRYPOINT\s*\(\s*($IDENTIFIER)\s*\)/)
{
my $function="__regs_$1";
$asm_functions{$dir}->{$function}=1;
}
elsif ($line =~ /^\s*DEFINE_THISCALL_WRAPPER\s*\(\s*($IDENTIFIER)\s*\)/)
{
my $function=$1;
$asm_functions{$dir}->{$function}=1;
$asm_functions{$dir}->{"__thiscall_$function"}=1;
}
elsif ($line =~ /__ASM_NAME\(\s*\"($IDENTIFIER)\"\s*\)/)
{
my $function=$1;
$asm_functions{$dir}->{$function}=1;
}
}
close($fh);
}
else
{
err("unable to open '$filename' for reading: $!\n");
exit 1;
}
}
sub fix_c_file($$)
{
my ($rootdir, $filename) = @_;
debug("***** Processing $filename\n");
if (open(my $fh, "<", "$rootdir$filename"))
{
@file = <$fh>;
close($fh);
}
else
{
err("unable to open '$filename' for reading: $!\n");
exit 1;
}
# Initialize the linefeed checker
my $lf_blacklist_extra;
if ($lf_blacklist{$filename})
{
$lf_blacklist_extra=join("|", keys %{$lf_blacklist{$filename}});
}
my $lf_ignore=0;
# Initialize the static stdcall checker
my (%st_statics, %st_refs);
my $st_prefix="";
my $modified;
$l=0;
while ($l < @file)
{
# Ifdef checker
if ($file[$l] =~ /^\s*#\s*if\s+($IDENTIFIER)\s*(\/\*.*)?$/ and
$undefs{$1})
{
print "$filename:",$l+1,": $1 might be undefined\n";
}
# Zero-flag checker
if ($file[$l] =~ /[^&]&[^&]/)
{
my $line=$file[$l];
debug("zflags: $line");
my %warned;
while ($line =~ s/([^&,({= ]\s*[&]\s*)($IDENTIFIER)\b/$1 1/)
{
debug("zflags1: $2 -> $line");
if ($zeroes{$2} and !$warned{$2})
{
print "$filename:",$l+1,": '&' with zero-flag $2\n";
$warned{$1}=1;
}
}
while ($line =~ s/\b($IDENTIFIER)(\s*&[^&])/1 $2/)
{
debug("zflags2: $1 -> $line");
if ($zeroes{$1} and !$warned{$1})
{
print "$filename:",$l+1,": '&' with zero-flag $1\n";
$warned{$1}=1;
}
}
if (%warned)
{
$line=$file[$l];
$line =~ s/^\s*//;
print " $line";
}
}
# Static stdcall checker
if ($file[$l] =~ /^\s*static(?:\s+$IDENTIFIER\s*\**)+\s+(?:$stdcall_re)\s+($IDENTIFIER)\s*(?:\(|$)/)
{
debug("$filename: static $1\n");
push @{$st_statics{$1}}, $l;
$st_prefix="";
}
elsif ("$st_prefix $file[$l]" =~ /^\s*static(?:\s+$IDENTIFIER+\s*\**)+\s+(?:$stdcall_re)\s+($IDENTIFIER)\s*(?:\(|$)/)
{
debug("$filename: static $1\n");
push @{$st_statics{$1}}, $l;
$st_prefix="";
}
elsif ($file[$l] =~ /^\s*static(?:\s+$IDENTIFIER\s*\**)*\s*$/)
{
$st_prefix=$file[$l];
chomp $st_prefix;
}
else
{
my $s=$file[$l];
while ($s =~ s/(^|[\{\(\)&=?:,])\s*($IDENTIFIER)\s*(?![\(a-zA-Z0-9_])/$1/)
{
#debug("$filename: & $2\n");
$st_refs{$2}=1;
}
$st_prefix="";
}
# NULL cast checker
# Ignore the '#define foo(xxx) NULL' lines
if ($file[$l] !~ /^\s*#/)
{
my $cast=$file[$l];
$cast =~ s/\(\s*$IDENTIFIER(?:\s+$IDENTIFIER|\s*\*)*\s*\*\s*\)\s*(?:NULL|0L?)(?!\w|[0-9])/NULL/g;
if ($cast =~ /\(\s*($IDENTIFIER)\s*\)\s*(?:NULL|0L?)(?!\w|[0-9])/)
{
# There may be others but if that happens
# they will be removed manually
$cast =~ s/\(\s*$1\s*\)\s*(?:NULL|0L?)(?!\w|[0-9]|\s*\)\s*->)/NULL/g if ($pointers{$1});
}
if ($cast ne $file[$l])
{
$file[$l]=$cast;
$modified=1;
}
}
# Linefeed processing
# This may read more lines so this should be done last
$lf_set_ignore=0;
my $fixed;
if ($file[$l] =~ /^(.*?\bok\s*\()/)
{
$fixed=fix_lf(1, 0, 2, length($1));
}
elsif ($file[$l] =~ /^(.*?\btrace\s*\()/)
{
$fixed=fix_lf(1, 1, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\b(?:WINE_)?(?:ERR|FIXME|TRACE|WARN)(?:_\s*\(\w+\))?\s*\()/)
{
$fixed=fix_lf(1, 1, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\b(?:WINE_)?(?:ERR|FIXME|TRACE|WARN)_\s*\(\s*[a-z]+\s*\)\s*\()/)
{
$fixed=fix_lf(1, 1, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\bshader_addline\s*\()/)
{
# This is a wined3d trace function
$fixed=fix_lf(1, 1, 2, length($1));
}
elsif ($file[$l] =~ /^(.*?\b(?:mcy_|parser_|xyy)?(?:chat|warning)\s*\()/)
{
# Error and warning reporting functions used in tools/
$fixed=fix_lf(1, 0, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\berror\s*\()/)
{
# Error reporting functions used in tools/
$fixed=fix_lf(1, 0, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\bparser_error\s*\()/)
{
# Error reporting function used in tools/ that must not have
# a trailing '\n'
$fixed=fix_lf(0, 0, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\berror_loc\s*\()/)
{
# Error reporting function used in tools/widl/
$fixed=fix_lf(1, 0, 1, length($1));
}
elsif ($file[$l] =~ /^(.*?\b(?:error|warning)_loc_info\s*\()/)
{
# Error and warning reporting functions used in tools/widl/
$fixed=fix_lf(1, 0, 2, length($1));
}
elsif ($file[$l] =~ /^(.*?\binternal_error\s*\()/)
{
# Error reporting function used in tools/wrc/
$fixed=fix_lf(1, 0, 3, length($1));
}
elsif ($lf_ignore and $file[$l] =~ /^[{}]/)
{
verbose("$filename:",$l+1,": resuming checks\n");
$lf_ignore=0;
}
if (defined $fixed)
{
# fix_lf() successfully checked this line
if (!$lf_ignore and !$lf_set_ignore and
$fixed ne $file[$l] and
$lf_blacklist_extra and $file[$l] =~ m!$lf_blacklist_extra!)
{
# Mark this blacklist entry as used
foreach my $re (keys %{$lf_blacklist{$filename}})
{
if ($file[$l] =~ /$re/)
{
delete $lf_blacklist{$filename}->{$re};
verbose("$filename:",$l+1,": matched $re\n");
last;
}
}
$lf_set_ignore=1;
}
if ($lf_ignore)
{
if (!$lf_set_ignore and $fixed eq $file[$l])
{
# We found a trace that looks ok so resume the checks
my $line=$file[$l];
$line =~ s/^\s*//;
verbose("$filename:",$l+1,": resuming checks due to: $line");
$lf_ignore=0;
}
}
else
{
if ($lf_set_ignore)
{
my $line=$file[$l];
$line =~ s/^\s*//;
verbose("$filename:",$l+1,": ignoring further errors due to: $line");
$lf_ignore=1;
}
elsif ($fixed ne $file[$l])
{
$file[$l]=$fixed;
$modified=1;
$fixed =~ s/^\s*//;
verbose("$filename:",$l+1,": fixed $fixed");
}
}
}
$l++;
}
if ($modified)
{
if (open(my $fh, ">", "$rootdir$filename"))
{
print $fh @file;
close($fh);
}
else
{
err("unable to open '$filename' for writing: $!\n");
}
}
# Check for unused linefeed blacklist entries
if ($lf_blacklist{$filename})
{
foreach my $re (keys %{$lf_blacklist{$filename}})
{
print STDERR "$filename: unused linefeed blacklist: $re\n";
}
}
delete $lf_blacklist{$filename};
# Static stdcall checker
foreach my $func (sort { $st_statics{$a}->[0] <=> $st_statics{$b}->[0] } keys %st_statics)
{
if (!$st_refs{$func})
{
if ($static_ignore{$filename}->{$func})
{
verbose("$filename: ignored static stdcall $func\n");
delete $static_ignore{$filename}->{$func};
}
else
{
print "***** $filename ", join(" ", @{$st_statics{$func}}), "\n";
$st_prefix="";
foreach my $line (@file)
{
if ($line =~ /\b$func\b/)
{
print " $st_prefix $line";
$st_prefix="";
}
elsif ($line =~ /^\s*static(?:\s+$IDENTIFIER\s*\**)*\s*$/)
{
$st_prefix=$line;
chomp $st_prefix;
}
else
{
$st_prefix="";
}
}
print "\n";
}
}
}
foreach my $func (keys %{$static_ignore{$filename}})
{
print "$filename:$func not used\n";
}
delete $static_ignore{$filename};
}
sub fix_rc_file($$)
{
my ($rootdir, $filename) = @_;
debug("***** Processing $filename\n");
if (open(my $fh, "<", "$rootdir$filename"))
{
@file = <$fh>;
close($fh);
}
else
{
err("unable to open '$filename' for reading: $!\n");
exit 1;
}
my $modified;
$l=0;
while ($l < @file)
{
my $line=$file[$l];
# Fix extraneous spaces in '...'
$line =~ s/\.(?: ?\.){2-5}/.../g;
if ($filename =~ m!Si\.rc$!)
{
# Slovenian requires a space before '...'
$line =~ s/([^ [])\.{3}/$1 .../g;
}
else
{
# Other languages say there should be no space before '...'
# Except English where it's a bit ambiguous but where there
# usually is no space in computer programs
$line =~ s/([^,*]) *\.{3}/$1.../g;
}
# Remove spaces before '\n'
$line =~ s/ +\\n/\\n/g;
# Fix SUBLANGs
if ($line !~ /^\s*#/ and
$line =~ /\b(LANG_[A-Z]+)\s*,\s*(SUBLANG_[A-Z]+)\b/)
{
my ($lang, $sublang)=($1, $2);
if ($lang eq "LANG_NEUTRAL")
{
if ($sublang ne "SUBLANG_NEUTRAL")
{
print "$filename:",$l+1,": expected LANG_NEUTRAL, SUBLANG_NEUTRAL for language-independent resource\n";
}
}
elsif (!$standard_sublangs{$sublang} and
$sublang =~ /^SUB(LANG_[A-Z]+)(?:_|$)/ and $1 ne $lang)
{
print "$filename:",$l+1,": $sublang does not match $lang\n";
}
elsif (!exists $lang_default{$lang})
{
print "$filename:",$l+1,": unknown language $lang\n";
}
elsif ($lang eq "LANG_RUSSIAN")
{
# FIXME: Say nothing for now until the SUBLANG_RUSSIAN_MOLDAVIA
# situation is resolved
}
elsif ($lang eq "LANG_GERMAN" and $sublang eq "SUBLANG_DEFAULT" and
$filename =~ m!kernel32/tests/resource\.rc$!)
{
# This is a test resource, presumably the SUBLANG_DEFAULT
# is important
# FIXME: Though maybe not
}
elsif (!$lang_manysubs{$lang})
{
# There is only one sublanguage
if ($lang_default{$lang} eq $sublang and $sublang ne "SUBLANG_DEFAULT")
{
# So it should be specified with SUBLANG_DEFAULT
$line =~ s/\b$lang\s*,\s*$sublang\b/$lang, SUBLANG_DEFAULT/;
}
}
elsif ($lang_anysub{$lang})
{
# This language has many sublanguages, and sublanguage-specific
# translations
if ($lang eq "LANG_ENGLISH")
{
# FIXME: Leave LANGUAGE_ENGLISH, SUBLANG_DEFAULT alone
# for now
}
elsif ($sublang eq "SUBLANG_DEFAULT")
{
# It's better to use the explicit name for the default
# sublanguage: it's clearer for the next translator.
$line =~ s/\b$lang\s*,\s*SUBLANG_DEFAULT\b/$lang, $lang_default{$lang}/;
}
}
else
{
# Although this language has many sublanguages, we believe
# that all the current translations are neutral.
if ($sublang eq "SUBLANG_DEFAULT")
{
$line =~ s/\b$lang\s*,\s*SUBLANG_DEFAULT\b/$lang, SUBLANG_NEUTRAL/;
}
elsif ($sublang eq $lang_default{$lang})
{
$line =~ s/\b$lang\s*,\s*$lang_default{$lang}\b/$lang, SUBLANG_NEUTRAL/;
}
elsif ($sublang ne "SUBLANG_NEUTRAL")
{
# Warn for non-neutral, non-default translations.
# Maybe we finally have per-sublanguage translations?
print "$filename:",$l+1,": $lang has an unexpected non neutral translation: $sublang\n";
}
}
}
if ($line ne $file[$l])
{
verbose("$filename:",$l+1,": fixed $line");
$file[$l]=$line;
$modified=1;
}
$l++;
}
if ($modified)
{
if (open(my $fh, ">", "$rootdir$filename"))
{
print $fh @file;
close($fh);
}
else
{
err("unable to open '$filename' for writing: $!\n");
}
}
}
sub fix_so($$$$)
{
my ($rootdir, $so_file, $spec_files, $obj_files)=@_;
return if (!defined $so_file or !@$obj_files);
my ($is_exe, $is_test);
$is_exe=1 if ($so_file =~ /\.exe\.so$/);
$is_test=1 if ($so_file =~ /_test\.exe\.so$/);
if (!@$spec_files and !$is_exe)
{
# This is not a Wine dll or exe so we have no idea
# what should or should not be exported
return;
}
my %spec_apis;
foreach my $spec_file (@$spec_files)
{
if (open(my $fh, "<", "$rootdir$spec_file"))
{
while (my $line = <$fh>)
{
next if ($line =~ /^\s*(?:#|$)/);
chomp $line;
if ($line =~ /^\s*(?:\d+|@)\s+\w+\s+(?:$SPECOPT)*\$?$MANGLEDIDENT\s*\([^)]*\)\s+($SPECIDENT)\s*(?:#.*)?$/)
{
my $identifier=$1;
$spec_apis{$identifier}=1 if ($identifier !~ /\./);
}
elsif ($line =~ /^\s*(?:\d+|@)\s+\w+\s+(?:$SPECOPT)*($SPECIDENT)\s*\([^)]*\)\s*(?:#.*)?$/)
{
my $identifier=$1;
$spec_apis{$identifier}=1 if ($identifier !~ /\./);
}
elsif ($line =~ /^\s*(?:\d+|@)\s+stub\s+(?:$SPECOPT)*($SPECIDENT)(?:@\d+)?\s*(?:#.*)?$/)
{
my $identifier=$1;
$spec_apis{$identifier}=1 if ($identifier !~ /\./);
}
elsif ($line =~ /^\s*(?:\d+|@)\s+stub\s+(?:$SPECOPT)*$MANGLEDIDENT\s*(?:#.*)?$/)
{
# Stub with only a mangled name -> no use to us
}
elsif ($line =~ /^\s*\d+\s+stub\s+@\s*(?:#.*)?$/)
{
# Unnamed stub -> no use to us
}
elsif ($line =~ /^\s*(?:\d+|@)\s+extern\s+(?:$SPECOPT)*\$?$MANGLEDIDENT\s+($SPECIDENT)\s*(?:#.*)?$/)
{
my $identifier=$1;
$spec_apis{$identifier}=1 if ($identifier !~ /\./);
}
elsif ($line =~ /^\s*(?:\d+|@)\s+extern\s+(?:$SPECOPT)*($SPECIDENT)\s*(?:#.*)?$/)
{
my $identifier=$1;
$spec_apis{$identifier}=1 if ($identifier !~ /\./);
}
elsif ($line =~ /^\s*\d+\s+equate\s/)
{
# No use to us
}
else
{
err("$spec_file: unknown line format\n $line\n");
}
}
close($fh);
}
else
{
err("unable to open '$spec_file' for reading: $!\n");
exit 1;
}
}
my (%idl_ignore, %obj_exports, %obj_references);
foreach my $obj_file (@$obj_files)
{
my ($idl_cs, $idl_proxy);
my $idl_file=$obj_file;
if ($idl_file =~ s/_[csp]\.o$/.idl/ and -f "$rootdir$idl_file")
{
$idl_cs=1 if ($obj_file =~ /_[cs]\.o$/);
$idl_proxy=1 if ($obj_file =~ /_p\.o$/);
}
if (open(my $fh, "objdump -t \"$rootdir$obj_file\" |"))
{
while (my $line = <$fh>)
{
if ($line =~ /^.*\s\.text\s+[0-9a-f]+\s+(?:\.hidden\s+)?([A-Za-z_][A-Za-z0-9_]*)$/)
{
my $symbol=$1;
if ($idl_cs)
{
$idl_ignore{$symbol}=1;
}
elsif ($idl_proxy and $symbol =~ /_(?:Proxy|Stub)$/)
{
$idl_ignore{$symbol}=1;
}
else
{
$obj_exports{$symbol}=1;
$obj_references{$symbol}++;
}
}
elsif ($line =~ /^.*\s\*UND\*\s+[0-9a-f]+\s+(?:\.hidden\s+)?([A-Za-z_][A-Za-z0-9_]*)$/)
{
$obj_references{$1}++;
}
}
close($fh);
}
else
{
err("unable to analyze '$obj_file': $!\n");
exit 1;
}
}
my $dir=dirname($so_file);
if (open(my $fh, "nm -D \"$rootdir$so_file\" |"))
{
while (my $line = <$fh>)
{
if ($line =~ /^[0-9a-f]+\sT\s(\w+)$/)
{
my $function=$1;
if (!$obj_exports{$function})
{
# We're importing this function, not exporting it!
}
elsif (($obj_references{$function} || 0) > 1)
{
# This function is used in more than one object file
# so it cannot be made static.
}
elsif ($idl_ignore{$function})
{
# These are widl-generated functions. They are meant to
# be used from other object files, but widl cannot know
# whether that will actually be the case or not.
# So these functions cannot be made static.
}
elsif ($asm_functions{$dir}->{$function})
{
# Functions implemented in assembly, or referenced from
# assembly code, cannot be made static due to gcc
# limitations.
}
elsif ($spec_apis{$function})
{
# These are meant to be exported
}
elsif ($is_exe and $function =~ /^w?(?:main|WinMain)$/)
{
# Executables are supposed to export these.
}
elsif ($is_test and $function =~ /^(?:broken$|wine_dbgstr_[aw]n?$|winetest_)/)
{
# Tests export these because of wine/test.h
}
elsif ($export_ignore{$dir}->{$function})
{
delete $export_ignore{$dir}->{$function};
}
else
{
print "$so_file: $function should be made static\n";
}
}
}
close($fh);
}
else
{
err("unable to analyze '$so_file': $!\n");
exit 1;
}
foreach my $func (keys %{$export_ignore{$dir}})
{
print "$dir:$func not used\n";
}
delete $export_ignore{$dir};
}
sub fix_tree($$$$$$)
{
my ($rootdir, $filter, $collect, $fix_c, $fix_rc, $fix_so)=@_;
my @dirs=("");
while (@dirs)
{
my $dir=pop @dirs;
if (opendir(my $dh, "$rootdir$dir"))
{
my ($so_file, @spec_files, @obj_files);
foreach my $dentry (readdir($dh))
{
next if ($dentry eq "." or $dentry eq "..");
$dentry="$dir$dentry";
if (-d "$rootdir$dentry")
{
if (-l "$rootdir$dentry")
{
verbose("skipping '$dentry' directory symbolic link\n");
next;
}
push @dirs, "$dentry/";
next;
}
next if ($filter and $dentry !~ /^$filter/);
if ($collect and $dentry =~ /\.[chly]$/)
{
collect($rootdir, $dentry);
}
elsif ($collect and $dentry eq "include/config.h.in")
{
collect($rootdir, $dentry);
}
elsif ($fix_c and $dentry =~ /\.[cly]$/)
{
fix_c_file($rootdir, $dentry);
}
elsif ($fix_rc and $dentry =~ /\.rc$/)
{
fix_rc_file($rootdir, $dentry);
}
elsif ($fix_so and $dentry =~ /\.so$/)
{
$so_file=$dentry;
}
elsif ($fix_so and $dentry =~ /\.spec$/)
{
push @spec_files, $dentry;
}
elsif ($fix_so and $dentry =~ /\.o$/ and $dentry !~ /\.cross\.o$/)
{
push @obj_files, $dentry;
}
}
closedir($dh);
fix_so($rootdir, $so_file, \@spec_files, \@obj_files) if ($fix_so);
}
else
{
err("unable to open the '$dir' directory: $!\n");
}
}
}
#####
#
# Main
#
#####
my ($opt_c, $opt_rc, $opt_so, $opt_help, $opt_dir, $opt_filter);
use Getopt::Long;
my $rc=GetOptions("c" => \$opt_c,
"rc" => \$opt_rc,
"so" => \$opt_so,
"debug" => \$debug,
"verbose" => \$verbose,
"help" => \$opt_help
);
if ($rc)
{
$opt_dir=shift @ARGV if (@ARGV);
$opt_filter=shift @ARGV if (@ARGV);
if (@ARGV)
{
err("only one directory can be specified\n");
$rc=0;
}
$opt_dir||=".";
$opt_dir.="/" if ($opt_dir !~ m!/$!);
}
if (!$rc)
{
err("try running $name0 --help\n");
exit 2;
}
if (!defined $opt_c and !defined $opt_rc and !defined $opt_so)
{
$opt_c=$opt_rc=$opt_so=1;
}
$verbose=1 if ($debug);
if ($opt_help)
{
print "Usage: $name0 [--c|--rc|--so] [--verbose] [--debug] [--help] [dir [filter]]\n";
print "\n";
print "Checks for various types of errors in the Wine source.\n";
print "\n";
print "Options:\n";
print " dir The directory containing the Wine sources\n";
print " filter Only handle that specific subdirectory\n";
print " --c Fix the C files\n";
print " --rc Fix the resource files\n";
print " --so Check the API exported by .so files\n";
print " --verbose Print some details and progress information\n";
print " --debug Print lots of debug information\n";
print " --help Prints this help message\n";
exit 0;
}
### First pass: Collect information for the second pass
verbose("First pass...\n");
fix_tree($opt_dir, $opt_filter, 1, 0, 0, 0);
sub set_closure($@)
{
my $set=shift @_;
my $count=0;
while (1)
{
my $c=keys %$set;
last if ($count == $c);
$count=$c;
foreach my $map (@_)
{
while (my ($name, $value)=each %$map)
{
$set->{$name}=1 if ($set->{$value});
}
}
}
}
# Find all the macros that expand to __stdcall
my %stdcalls;
map { $stdcalls{$_}=1 } @stdcall_seeds;
set_closure(\%stdcalls, \%macros);
verbose("stdcall = ", join(" ", sort keys %stdcalls), "\n");
$stdcall_re=join("|", keys %stdcalls);
# Round up the macros that expand to 0
set_closure(\%zeroes, \%macros);
verbose("zeroes = ", join(" ", sort keys %zeroes), "\n");
# Round up the pointer types
set_closure(\%pointers, \%typedefs, \%macros);
verbose("pointers = ", join(" ", sort keys %pointers), "\n");
# Find all languages with more than one sublanguage
foreach my $name (keys %macros)
{
next if ($standard_sublangs{$name});
if ($name =~ /^SUB(LANG_[A-Z]+)(?:_[A-Z][A-Z_]+)?$/)
{
my $lang=$1;
if ($name !~ /^SUBLANG_(?:LOWER|UPPER)_SORBIAN_GERMANY$/ and
!exists $macros{$lang})
{
err("$name has no matching language definition\n");
}
my $val=$macros{$name};
my $indirect;
if ($val =~ /^SUBLANG_/)
{
$val=$macros{$val};
$indirect=1;
}
$val =~ s/^.*\(\s*((?:0x)?[0-9a-fA-F]+)\s*\).*$/$1/;
$val =~ s/^0x0*(?=0$|[1-9a-fA-F])//;
if ($val !~ /^[0-9a-fA-F]+$/)
{
err("unknown sublanguage type for $name: $macros{$name}\n");
exit 1;
}
elsif ($val ne "1")
{
$lang_manysubs{$lang}=1;
}
elsif (!$indirect or ($lang_default{$lang} || "SUBLANG_DEFAULT") eq "SUBLANG_DEFAULT")
{
$lang_default{$lang}=$name;
}
}
elsif ($name =~ /^(LANG_[A-Z]+)$/ and !$lang_default{$name})
{
$lang_default{$name}="SUBLANG_DEFAULT";
}
}
### Second pass: Actually fix files and report issues
verbose("Second pass...\n");
fix_tree($opt_dir, $opt_filter, 0, $opt_c, $opt_rc, $opt_so);
### Check for unused blacklist entries
if (-f "$opt_dir/configure.ac" and !$opt_filter)
{
if ($opt_c)
{
map { print "linefeed: $_ not found\n"; } sort keys %lf_blacklist;
map { print "static: $_ not found\n"; } sort keys %static_ignore;
}
if ($opt_rc)
{
map { print "$_ should not be in \%lang_anysub\n" if (!$lang_manysubs{$_}) } sort keys %lang_anysub;
}
if ($opt_so)
{
map { print "export: $_ not found\n"; } sort keys %export_ignore;
}
}
More information about the wine-devel
mailing list