1
0
mirror of synced 2025-01-19 01:14:04 +01:00

Release V2 - Merry Christmas!

This commit is contained in:
Bobby Dilley 2024-12-23 14:41:01 +00:00
parent d8e8bb5cc9
commit 368431dc83
146 changed files with 72284 additions and 4547 deletions

245
.clang-format Normal file
View File

@ -0,0 +1,245 @@
---
Language: Cpp
BasedOnStyle: Microsoft
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseColons: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Custom
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 140
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
KeepEmptyLinesAtEOF: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 1000
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
---

View File

@ -1,4 +1,4 @@
name: Lindbergh Loader CI
name: Build
on:
pull_request:
@ -7,19 +7,13 @@ on:
push:
branches:
- master
# NOTE: Manual releases for now, only currently
# testing with pre-releases and artifacts
# tags:
# - 'v*'
jobs:
ci:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repo
uses: actions/checkout@v4
@ -29,20 +23,3 @@ jobs:
context: .
push: false
outputs: type=local,dest=build
- name: Create build artifacts
uses: actions/upload-artifact@v3
if: github.event_name == 'pull_request'
with:
name: lindbergh-loader-${{ github.event.pull_request.head.sha }}
path: build/*
- name: Create pre-release
uses: "marvinpinto/action-automatic-releases@latest"
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: true
title: "Lindbergh Loader"
files: build/*

6
.gitignore vendored
View File

@ -1,5 +1,11 @@
bld
build/
test/
tmp/
*.bin
/*.conf
src/lindbergh/*.o
src/libxdiff/xdiff/*.o
src/libxdiff/*.a
src/libkswapapi/*.o
src/libsegaapi/*.o

View File

@ -10,7 +10,7 @@
"__USE_MISC"
],
"cppStandard": "gnu++17",
"cStandard": "c99",
"cStandard": "gnu99",
"intelliSenseMode": "linux-gcc-x86",
"forcedInclude": [
"${workspaceFolder}/../vscode-preinclude.h"

16
.vscode/settings.json vendored
View File

@ -1,14 +1,14 @@
{
"files.associations": {
"string.h": "c",
"rideboard.h": "c",
"serial.h": "c",
"jvs.h": "c",
"time.h": "c",
"stdarg.h": "c",
"input.h": "c",
"stddef.h": "c",
"ioctl.h": "c",
"segaeax.h": "c",
"passthrough.h": "c"
"array": "c",
"__tuple": "c",
"evdevinput.h": "c",
"input-event-codes.h": "c",
"pthread.h": "c",
"xf86vmode.h": "c"
},
"C_Cpp.errorSquiggles": "disabled",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x86",

75
CMakeLists.txt Normal file
View File

@ -0,0 +1,75 @@
cmake_minimum_required(VERSION 3.10)
project(Lindbergh)
# Set compiler and linker
set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_LINKER g++)
# Define output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
# Source files for various targets
file(GLOB LIND_OBJS "src/lindbergh/*.c" "src/lindbergh/*.cpp")
list(FILTER LIND_OBJS EXCLUDE REGEX "src/lindbergh/lindbergh.o")
list(FILTER LIND_OBJS EXCLUDE REGEX "src/lindbergh/evdevinput.o")
file(GLOB XDIFF_SRCS "src/libxdiff/xdiff/*.c")
# Custom compiler and linker flags
set(LINDBERGH_EXE -m32)
set(LINDBERGH_C_FLAGS -g -fPIC -m32 -Wall -Werror -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE)
#SET(CMAKE_C_FLAGS_DEBUG -g)
SET(CMAKE_C_FLAGS_RELEASE -O3)
set(LINDBERGH_CXX_FLAGS ${LINDBERGH_C_FLAGS} -std=c++11)
set(LIBXDIFF_C_FLAGS -DHAVE_CONFIG_H -fPIC -m32)
set(LIBSEGAAPI_CXX_FLAGS -m32 -fPIC -shared)
set(LIBSEGAAPI_LINKER_FLAGS -m32 -lFAudio)
set(SHARED_LINKER_FLAGS -m32 -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lSDL2 -lm -lpthread -shared -lstdc++ -nostdlib -lasound)
# Build executable for lindbergh
add_executable(lindyloader src/lindbergh/lindbergh.c src/lindbergh/evdevinput.c src/lindbergh/evdevinput.h)
set_target_properties(lindyloader PROPERTIES OUTPUT_NAME "lindbergh")
set_target_properties(lindyloader PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} LINK_FLAGS "-m32")
target_compile_options(lindyloader PRIVATE ${LINDBERGH_EXE})
# Build static library libxdiff.a with its own flags
add_library(xdiff STATIC ${XDIFF_SRCS})
set_target_properties(xdiff PROPERTIES OUTPUT_NAME xdiff ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} LINK_FLAGS "-m32")
target_compile_options(xdiff PRIVATE ${LIBXDIFF_C_FLAGS})
# Build shared library lindbergh.so
add_library(lindbergh SHARED ${LIND_OBJS})
set_target_properties(lindbergh PROPERTIES PREFIX "")
target_link_libraries(lindbergh xdiff ${SHARED_LINKER_FLAGS})
target_compile_options(lindbergh PRIVATE ${LINDBERGH_EXE})
# Build shared library libsegaapi.so
add_library(segaapi SHARED src/libsegaapi/opensegaapi.cpp)
target_link_libraries(segaapi FAudio ${LIBSEGAAPI_LINKER_FLAGS})
target_compile_options(segaapi PRIVATE ${LIBSEGAAPI_CXX_FLAGS})
# Build shared library libkswapapi.so
add_library(kswapapi SHARED src/libkswapapi/libkswapapi.c)
target_link_libraries(kswapapi ${SHARED_LINKER_FLAGS})
target_compile_options(kswapapi PRIVATE ${LINDBERGH_C_FLAGS})
# Build shared library libposixtime.so
add_library(posixtime SHARED src/libposixtime/libposixtime.c)
set_target_properties(posixtime PROPERTIES OUTPUT_NAME posixtime LINK_FLAGS "-m32")
add_custom_command(TARGET posixtime POST_BUILD
COMMAND ln -s -f libposixtime.so ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libposixtime.so.1
COMMAND ln -s -f libposixtime.so ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libposixtime.so.2.4)
target_compile_options(posixtime PRIVATE ${LINDBERGH_C_FLAGS})
# Custom clean rule
add_custom_target(cleanall
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/build
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/lindbergh/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libsegaapi/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libkswapapi/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libxdiff/*.a
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libxdiff/xdiff/*.o
)

View File

@ -4,33 +4,14 @@ RUN dpkg --add-architecture i386 \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
freeglut3-dev:i386 \
freeglut3:i386 \
gcc-multilib \
libglew-dev \
libopenal-dev:i386 \
libopenal1:i386 \
libstdc++5:i386 \
libxmu6:i386 \
libasound2-dev:i386 \
wget \
xorg-dev \
freeglut3-dev:i386 \
libsdl2-dev:i386 \
libfaudio-dev:i386 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /xenial-libs
RUN wget -q http://launchpadlibrarian.net/534757982/multiarch-support_2.23-0ubuntu11.3_i386.deb \
&& dpkg -i multiarch-support_2.23-0ubuntu11.3_i386.deb
RUN wget -q http://launchpadlibrarian.net/184146495/libalut0_1.1.0-5_i386.deb \
&& dpkg -i libalut0_1.1.0-5_i386.deb
RUN wget -q http://launchpadlibrarian.net/184146496/libalut-dev_1.1.0-5_i386.deb \
&& dpkg -i libalut-dev_1.1.0-5_i386.deb
WORKDIR /lindbergh-loader
COPY . .
RUN make
# Output binaries of build using the --output=PATH argument
FROM scratch AS binaries
COPY --from=lindbergh-build /lindbergh-loader/build/* /

438
LICENSE.md Normal file
View File

@ -0,0 +1,438 @@
Attribution-NonCommercial-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International Public License
("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-NC-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution, NonCommercial, and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
l. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
m. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
n. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce, reproduce, and Share Adapted Material for
NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-NC-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

View File

@ -1,36 +1,62 @@
CC=gcc -m32
CFLAGS = -g -O0 -fPIC -m32 -Wall -Werror -Wno-unused-variable -Wno-unused-function
LD = g++ -m32
LDFLAGS = -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lm -lpthread -shared -nostdlib -lasound
CC = gcc -m32 -pthread
CFLAGS = -g -fPIC -m32 -Wall -Werror -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE -Wno-char-subscripts
LD = g++ -m32
LDFLAGS = -Wl,-z,defs -rdynamic -static-libgcc -lc -ldl -lGL -lglut -lX11 -lSDL2 -lm -lpthread -shared -nostdlib -lasound -L./src/libxdiff -lxdiff
BUILD = build
XDIFF_SRCS = xdiffi.c xprepare.c xpatchi.c xmerge3.c xemit.c xmissing.c xutils.c \
xadler32.c xbdiff.c xbpatchi.c xversion.c xalloc.c xrabdiff.c
XDIFF_OBJS = $(patsubst %.c,src/libxdiff/xdiff/%.o,$(XDIFF_SRCS))
OBJS := $(patsubst %.c,%.o,$(wildcard src/lindbergh/*.c))
OBJS := $(filter-out src/lindbergh/lindbergh.o, $(OBJS))
all: lindbergh lindbergh.so libsegaapi.so libkswapapi.so
all: lindbergh libxdiff.a lindbergh.so libsegaapi.so libkswapapi.so libposixtime.so
lindbergh: src/lindbergh/lindbergh.c
lindbergh: src/lindbergh/lindbergh.c src/lindbergh/jvs.c src/lindbergh/jvs.h src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.h src/lindbergh/evdevinput.c
mkdir -p $(BUILD)
$(CC) src/lindbergh/lindbergh.c -o $(BUILD)/lindbergh
$(CC) src/lindbergh/lindbergh.c src/lindbergh/jvs.h src/lindbergh/jvs.c src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.c src/lindbergh/evdevinput.h -o $(BUILD)/lindbergh -lm
libxdiff.a: $(XDIFF_OBJS)
mkdir -p $(BUILD)
ar rcs src/libxdiff/libxdiff.a $(XDIFF_OBJS)
src/libxdiff/xdiff/%.o: src/libxdiff/xdiff/%.c
$(CC) -DHAVE_CONFIG_H -c $< -o $@
lindbergh.so: $(OBJS)
mkdir -p $(BUILD)
$(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o $(BUILD)/lindbergh.so
rm -f src/lindbergh/*.o
$(LD) $(OBJS) $(LDFLAGS) -o $(BUILD)/lindbergh.so
LIBSEGA_LD=gcc #clang
LIBSEGA_LDFLAGS=-m32 -O0 -g
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
libsegaapi.so: src/libsegaapi/segaapi.o
$(LIBSEGA_LD) $(LIBSEGA_LDFLAGS) src/libsegaapi/segaapi.o -L/usr/lib/i386-linux-gnu -lalut -fPIC -shared -o $(BUILD)/libsegaapi.so
rm -f src/libsegaapi/*.o
libsegaapi.so: src/libsegaapi/libsegaapi.o
gcc -m32 -O0 -g src/libsegaapi/libsegaapi.c -lFAudio -fPIC -shared -o $(BUILD)/libsegaapi.so
libkswapapi.so: src/libkswapapi/libkswapapi.o
$(LIBSEGA_LD) $(LIBSEGA_LDFLAGS) src/libkswapapi/libkswapapi.o -L/usr/lib/i386-linux-gnu -fPIC -shared -o $(BUILD)/libkswapapi.so
rm -f src/libkswapapi/*.o
$(CC) src/libkswapapi/libkswapapi.o -fPIC -shared -o $(BUILD)/libkswapapi.so
libposixtime.so:
$(CC) src/libposixtime/libposixtime.c src/libposixtime/libposixtime.h -m32 -shared -o $(BUILD)/libposixtime.so
ln -s -f libposixtime.so $(BUILD)/libposixtime.so.1
ln -s -f libposixtime.so $(BUILD)/libposixtime.so.2.4
# Clean rule
clean:
rm -f $(BUILD)/lindbergh.so
rm -f $(BUILD)/libsegaapi.so
rm -f $(BUILD)/lindbergh
rm -f src/lindbergh/*.o
rm -f src/libsegaapi/*.o
#clean all rule
cleanall:
rm -rf $(BUILD)
rm -f src/lindbergh/*.o
rm -f src/libsegaapi/*.o
rm -f src/libkswapapi/*.o
rm -f src/libxdiff/*.a
rm -f src/libxdiff/xdiff/*.o

View File

@ -1,83 +1,60 @@
[![Actions Status](https://github.com/dkeruza-neo/lindbergh-loader/actions/workflows/ci.yml/badge.svg)](https://github.com/dkeruza-neo/lindbergh-loader/actions)
# SEGA Lindbergh Emulator
This project emulates the SEGA Lindbergh, allowing games to run on modern Linux computers with an NVIDIA graphics card to be used as replacement hardware for broken Lindbergh systems in physical arcade machines.
You can view the supported titles [here.](docs/supported.md)
## Dependencies
First make sure you have up-to-date NVIDIA drivers and then install the following:
```
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install gcc-multilib
sudo apt install build-essential
sudo apt install freeglut3:i386
sudo apt install freeglut3-dev:i386
sudo apt install libglew-dev
sudo apt install xorg-dev
sudo apt install libopenal1:i386 libopenal-dev:i386
sudo apt install libalut-dev:i386 // You will need to find libalut-dev:i386, libalut0:i386 and multiarch-support:i386 from Ubuntu Xenial.
sudo apt install libxmu6:i386
sudo apt install libstdc++5:i386
sudo apt install libasound2-dev:i386
```
For Ubuntu 22.04 and above you'll need to download manually from Xenial.
```
wget -q http://launchpadlibrarian.net/534757982/multiarch-support_2.23-0ubuntu11.3_i386.deb \
&& dpkg -i multiarch-support_2.23-0ubuntu11.3_i386.deb
wget -q http://launchpadlibrarian.net/184146495/libalut0_1.1.0-5_i386.deb \
&& dpkg -i libalut0_1.1.0-5_i386.deb
wget -q http://launchpadlibrarian.net/184146496/libalut-dev_1.1.0-5_i386.deb \
&& dpkg -i libalut-dev_1.1.0-5_i386.deb
```
Note: The project has been tested to work on Ubuntu 22.04, and doesn't currently work on Ubuntu 23.10. Multiple packages such as `freeglut3:i386` are not available anymore on Debian Trixxie or Ubuntu 23.10.
This project emulates the SEGA Lindbergh, allowing games to run on modern Linux computers to be used as replacement hardware for broken Lindbergh systems in physical arcade machines. It supports both Intel and AMD CPUs as well as Intel, NVIDIA and AMD GPUs, surround sound audio, networking and JVS pass through.
## Building & Running
This emulator will need access to the input devices and serial devices on Linux. Before running this emulator you should add your user account to the following groups and then _restart your computer_.
First you will need to install the following dependencies.
```shell
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install git build-essential gcc-multilib freeglut3-dev:i386 libsdl2-dev:i386 libfaudio-dev:i386
```
This emulator will need access to the input devices and serial devices on your computer. You should add your user account to the following groups and then _restart your computer_.
```shell
sudo usermod -a -G dialout,input $USER
```
To build, run the makefile, and then copy the contents of the build directory into the game directory and run.
Then you should clone the repository, change directory into it and run make.
```
```shell
git clone git@github.com:dkeruza-neo/lindbergh-loader.git
cd lindbergh-loader
make
cp build/* ~/the-house-of-the-dead-4/disk0/elf/.
cd ~/the-house-of-the-dead-4/disk0/elf
```
You should then copy the contents of the build directory to your game directory and run `./lindbergh` for the game, or `./lindbergh -t` for test mode.
```shell
cp -a build/* /home/games/the-house-of-the-dead-4/disk0/elf/.
cd /home/games/the-house-of-the-dead-4/disk0/elf/.
./lindbergh
```
Some games will require extra libraries like `libposixtime.so`, which can be found in dumps of the Lindbergh CF image.
If you'd like to change game settings copy the default configuration file from the repository to your game directory.
A default configuration file is provided in `docs/lindbergh.conf`. It should be placed in the same folder the game is run from. If no config file is present a default setting will be used.
```shell
cp build/docs/lindbergh.conf /home/games/the-house-of-the-dead-4/disk0/elf/.
nano lindbergh.conf
```
Do not run this as root, instead use the usergroups for input/dialout to give the emulator access to what it needs. Lindbergh games expect full control of the Linux OS and with root privilages it is possible that they could cause damage to your computer.
Configuration options and supported games are explained in the [guide](docs/guide.md).
A `lindbergh` executable is provided in the build directory to easily run the games. Place it in the same directory as the game elf, and run `./lindbergh` to automatically start the game with the correct environment variables set, or run `./lindbergh -t` for test mode.
## License
## Controls
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://github.com/lindbergh-loader/">Lindbergh Loader</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://github.com/lindbergh-loader/">Lindbergh Loader Development Team</a> is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt=""></a></p>
Currently the controls are set up for The House of the Dead 4.
| Key | Mapping |
|-------------|----------------|
| t | Test |
| s | Service |
| 5 | Coin 1 |
| 1 | Player 1 Start |
| Right Click | Reload |
| Left Click | Shoot |
Controls can be modified in the `lindbergh.conf` file.
Our project is open source, and our primary goal is to preserve and maintain Lindbergh arcade machines, ensuring they continue to operate in arcades. We encourage individuals to use the information provided for their own open source projects and contribute to the development of the loader to improve it for the benefit of the community. However, we do not permit the use of any of our code in commercial ventures without prior consent from the Lindbergh Loader Development Team. If we become aware of any such use, we reserve the right to take legal action.
## Thanks
This project has been built by referencing earlier projects by Teknoparrot and JayFoxRox and from contributions by Doozer, Rolel, dkeruza-neo, Caviar-X and RetroFan with extensive testing by Francesco - thanks to all of them!
This project has been built by referencing various earlier projects and would like to extend it's thanks to everyone that has contributed to the Lindbergh scene.
## Takedown Notices
The Lindbergh Loader Development Team respects intellectual property rights and is committed to ensuring that no copyrighted material is shared without proper authorization. If you believe that we are infringing on your intellectual property or have any concerns regarding our activities, please email us at bobby [at] dilley [dot] uk. We are more than happy to address any issues and discuss them further.

View File

@ -1,94 +0,0 @@
2SPICY
After Burner
After Burner Climax
After Burner Climax [Rev.A]
After Burner Climax [Rev.B]
After Burner Climax SDX
After Burner Climax SDX [Rev.A]
AMI-GYO
Ami No.3
Answer x Answer
Answer x Answer 2
Answer x Answer Live!
Blackjack Nailed Ace
Club Majesty - Extend - Cloud Nine
Club Majesty - Extend - Wheel Maniacs
Club Majesty Formal: Attractive Deck Poker
Club Majesty Formal: Cosmic Challenge
Club Majesty Formal: Cosmic Challenge [Rev.C]
Club Majesty: Gatling Poker
Club Majesty: Where's Wally!
Derby Owners Club 2008 Feel the Rush
Derby Owners Club 2009 Ride for the live
Ghost Squad Evolution
Harley Davidson King of the Road
HOTD4
HOTD4SP
HOTD EX
Hummer
Hummer Extreme
Hummer Extreme Edition MDX
Info Station 2 [Rev.C]
Initial D Arcade Stage 4
Initial D Arcade Stage 4 [Rev.A]
Initial D Arcade Stage 4 [Rev.B]
Initial D Arcade Stage 4 [Rev.C]
Initial D Arcade Stage 4 [Rev.D]
Initial D Arcade Stage 4 [Rev.G]
Initial D Arcade Stage 5
Initial D Arcade Stage 5 Exp 2.0
Initial D Arcade Stage 5 [Rev.A]
Let's Go Jungle
Let's Go Jungle Special
MJ4 Evolution
Outrun 2 SP SDX
Outrun 2 SP SDX [Rev.A]
Primeval Hunt
Rambo
Rambo (China)
Router Update (for VTF)
R-Tuned
Sangokushi Taisen 2
Sangokushi Taisen 3
Sega Network Casino Club STD
Sega Network Casino Club Ver.2
Sega Network Casino Club Ver.2 [Rev.B]
Sega Network Casino Club Ver.3
Sega Race TV
Sengokushi Taisen3 War Begins
Star Horse 2 Fifth Expansion [Rev.B]
Star Horse 2 Fifth Expansion [Rev.D]
Star Horse 2 Fifth Expansion [Rev.E]
Star Horse 2 Final Destination
Starhorse 2 Fourth Ambition
Star Horse 2 Fourth Ambition
Star Horse 2 New Generation
Star Horse 2 Second Fusion
Star Horse 2 Third Evolution
Star Horse 2 Third Evolution (Hong Kong)
Taisen Mahjong 4 (1.0)
Taisen Mahjong 4 (2.0)
Taisen Mahjong 4 (3.0)
Taisen Mahjong 4 (4.0)
Taisen Mahjong 4 (5.0)
Taisen Mahjong 4 (6.0)
Taisen Mahjong 4 (7.0)
Taisen Mahjong 4 (8.0)
toAmi-Gyo
to AMI GYO
VBIOS Update (2.0)
VBIOS Update (3.0)
VBIOS Update (for VTF)
Virtua Fighter 5
Virtua Fighter 5 Final Showdown
Virtua Fighter 5 Final Showdown [Rev.A]
Virtua Fighter 5 R
Virtua Fighter 5 [Rev.A]
Virtua Fighter 5 [Rev.B]
Virtua Fighter 5 [Rev.E]
Virtua Fighter 5 R [Rev.D]
Virtua Tennis 3
World Club Championship Football 2008-2009
World Club Championship Football 2009-2010 [ASIA]
World Club Championship Football 2009-2010 [JP]

80
docs/guide.md Normal file
View File

@ -0,0 +1,80 @@
# Guide
All configurable options are set and explained in the `lindbergh.conf` file, and should be resonably easy to understand. This document further explains some of those setup options.
## Controller Setup
There are 2 modes for the controller setup in the emulator, these are set using the `INPUT_MODE` flag in the configuration file.
### Input Mode 0
In this input mode, both input mode 1 and input mode 2 are active.
### Input Mode 1
In the first input mode, the keys on the keyboard are used to control the game play. If playing a light gun game, the mouse pointer in the window is used as the player 1 light gun. There are no configurable options in this mode.
### Input Mode 2
In the second input mode, inputs are taken directly from the evdev library in linux and so you can configure additional devices such as light guns, controllers and steering wheels.
To list the available inputs you should type:
```
./lindbergh --lits-inputs
```
From there you will be able to see the controllers and all of the inputs support. Then in the config file you should map an arcade input to a controller input as follows.
```
PLAYER_1_BUTTON_UP XBOX_CONTROLLER_BTN_UP
ANALOGUE_1 XBOX_CONTROLLER_ABS_X
```
You can map digital controls to analogue controls. The analogue value will be set to the digital value, such that if the button isn't pressed it will be set to 0, and if the button is pressed it will be set to MAX. This is useful if your controller doesn't have analogue accelerator or break buttons.
```
ANALOGUE_0 XBOX_CONTROLLER_BUTTON_BR
```
You can map analogue controls to digital controls too. For each analogue input, there are 2 more inputs created ending in _MAX and _MIN. These are digital controls that will be triggered when the analogue input is either at the minimum or maximum value. This can be useful if you'd like to use an analogue stick to control a fighting game for example.
```
PLAYER_1_BUTTON_UP XBOX_CONTROLLER_ABS_Y_MAX
PLAYER_1_BUTTON_DOWN XBOX_CONTROLLER_ABS_Y_MIN
PLAYER_1_BUTTON_LEFT XBOX_CONTROLLER_ABS_X_MIN
PLAYER_1_BUTTON_RIGHT XBOX_CONTROLLER_ABS_X_MAX
```
## Audio
There are currently no audio options that you can set. If you have a stereo sound card installed then the audio will be downmixed to stereo. If you have a 5.1 sound card installed and the game supports surround sound, each surround channel should be passed through properly and should play sound as it was originally intended.
## Supported Games
The follow list of games are supported. It is worth noting that there are multiple releases of these games, and some specific releases may not be supported.
| Game Name | Game ID | DVP | NVidia | Intel (Mesa) | AMD (Mesa) | AMD (proprietary) |
| ------------------------------- | ------- | -------- | ------ | ------------ | ---------- | ----------------- |
| 2 Spicy | SBMV | DVP-0027 | ✓ | ✓ | ✓ | ✓ |
| After Burner Climax | SBLR | DVP-0009 | ✓ | ✓ | ✓ | |
| Ghost Squad Evolution | SBNJ | DVP-0029 | ✓ | ✓ | ✓ | ✓ |
| Harley Davidson | SBRG | DVP-5007 | ✓ | ✓ | ✓ | ✓ |
| Hummer Extreme | SBST | DVP-0079 | ✓ | ✓ | ✓ | ✓ |
| Hummer | SBQN | DVP-0057 | ✓ | ✓ | ✓ | ✓ |
| Let's Go Jungle | SBLU | DVP-0011 | ✓ | ✓ | ✓ | |
| Let's Go Jungle Special | SBNR | DVP-0036 | ✓ | ✓ | ✓ | |
| Outrun 2 SP SDX | SBMB | DVP-0015 | ✓ | ✓ | ✓ | ✓ |
| R-Tuned | SBQW | DVP-0060 | ✓ | ✓ | ✓ | ✓ |
| Race TV | SBPF | DVP-0044 | ✓ | ✓ | ✓ | ✓ |
| Rambo | SBQL | DVP-0069 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead 4 | SBLC | DVP-0003 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead 4 Special | SBLS | DVP-0010 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead Ex | SBRC | DVP-0063 | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 | SBLM | DVP-0008 | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 R | SBQU | DVP-5004 | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 FS | SBUV | DVP-5019 | ✓ | ✓ | ✓ | ✓ |
| Initial D 4 | SBNK | DVP-0030 | ✓ | ✓ | ✓ | ✓ |
| Initial D 5 | SBTS | DVP-0075 | ✓ | ✓ | ✓ | |
| Virtua Tennis 3 | SBKX | DVP-0005 | ✓ | ✓ | ✓ | ✓ |
| Primeval Hunt | SBPP | DVP-0048 | ✓ | ✓ | ✓ | ✓ |

View File

@ -1,25 +1,47 @@
# SEGA Lindbergh Emulator Configuration File
# Written by Bobby Dilley
# Set the colour of the lindbergh to change the Segaboot logo
# Possible colours are: YELLOW and RED
# LINDBERGH_COLOUR YELLOW
# Choice of resolutions
# 640 x 480
# 800 x 600
# 1024 x 768
# 1280 x 1024
# 800 x 480
# 1024 x 600
# 1280 x 768
# 1360 x 768
# All config options here are commented out by default.
# Uncomment them to enable that configuration override option.
# Set the requested dip switch width here
# WIDTH 640
# WIDTH 1360
# Set the requested dip switch height here
# HEIGHT 480
# HEIGHT 768
# Set if the emulator should go full screen
# FULLSCREEN 0
# Sets the Input Mode
# Mode 0: will use both SDL/X11 and EVDEV inputs (default)
# Mode 1: will use SDL/X11 inputs only
# Mode 2: will use EVDEV raw inputs only, which should be configured at the bottom of the settings file
# INPUT_MODE 0
# Set to 1 if you want to disable SDL (Fixes SRTV boost bar)
# NO_SDL 1
# Set the Region ( JP/US/EX )
# REGION EX
# Set if you want the game to be Free Play
# FREEPLAY 1
# Set the different keys used to control the games.
# You can find out the key numbers by running `xev` on linux.
# TEST_KEY 28
# PLAYER_1_START_KEY 10
# PLAYER_1_SERVICE_KEY 39
# PLAYER_1_COIN_KEY 14
# PLAYER_1_UP_KEY 111
# PLAYER_1_DOWN_KEY 116
# PLAYER_1_LEFT_KEY 113
# PLAYER_1_RIGHT_KEY 114
# PLAYER_1_BUTTON_1_KEY 24
# PLAYER_1_BUTTON_2_KEY 25
# PLAYER_1_BUTTON_3_KEY 26
# PLAYER_1_BUTTON_4_KEY 27
# Set if the emulator should emulate JVS and use the keyboard/mouse for controls.
# If this is set to 0, then the emulator will route the traffic to the serial device
@ -56,29 +78,76 @@
# Define the path to the eeprom.bin file
# EEPROM_PATH eeprom.bin
# Set if the emulator should go full screen
# FULLSCREEN 0
# Set the Region ( JP/US/EX )
# REGION EX
# Set if you want the game to be Free Play
# FREEPLAY 1
# Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown)
# GPU_VENDOR 0
# Set if you want to see debug messages in the console
# DEBUG_MSGS 1
# Set the different keys used to control the games.
# You can find out the key numbers by running `xev` on linux.
# TEST_KEY 28
# PLAYER_1_START_KEY 10
# PLAYER_1_SERVICE_KEY 39
# PLAYER_1_COIN_KEY 14
# PLAYER_1_UP_KEY 111
# PLAYER_1_DOWN_KEY 116
# PLAYER_1_LEFT_KEY 113
# PLAYER_1_RIGHT_KEY 114
# PLAYER_1_BUTTON_1_KEY 24
# PLAYER_1_BUTTON_2_KEY 25
# PLAYER_1_BUTTON_3_KEY 26
# PLAYER_1_BUTTON_4_KEY 27
# Set to true if you experience flickering in hummer
# HUMMER_FLICKER_FIX 1
# Set to keep the aspect ratio (4:3) in games like Sega Race TV and Primeval Hunt
# KEEP_ASPECT_RATIO 1
# Set to 0 if you want to disable the Glare effect in OutRun
# OUTRUN_LENS_GLARE_ENABLED 0
# Set to 1 if you want to limit the FPS in games that are not limited like OutRun2
# FPS_LIMITER_ENABLED 1
# Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1)
# FPS_TARGET 60
# Set to 1 if you want to render LGJ using the mesa patches instead of nVidia (fixes some glitches)
# LGJ_RENDER_WITH_MESA 1
# Set the Primeval Hunt mode
# Mode 0: Leaves everything as default
# Mode 1: No touch screen (Default mode)
# Mode 2: Side by Side
# Mode 3: 3ds mode 1 (Touch screen to the right)
# Mode 4: 3ds mode 2 (Touch screen to the bottom)
# PRIMEVAL_HUNT_MODE 1
# Set the colour of the lindbergh to change the Segaboot logo
# Possible colours are: YELLOW and RED
# LINDBERGH_COLOUR YELLOW
# EVDEV MODE (Input Mode 2)
# To find the value pairs for these run ./lindbergh --list-controllers
# PLAYER_1_BUTTON_START AT_TRANSLATED_SET_2_KEYBOARD_KEY_1
# PLAYER_1_BUTTON_SERVICE AT_TRANSLATED_SET_2_KEYBOARD_KEY_S
# PLAYER_1_BUTTON_UP AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP
# PLAYER_1_BUTTON_DOWN AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN
# PLAYER_1_BUTTON_LEFT AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT
# PLAYER_1_BUTTON_RIGHT AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT
# PLAYER_1_BUTTON_1 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q
# PLAYER_1_BUTTON_2 AT_TRANSLATED_SET_2_KEYBOARD_KEY_W
# PLAYER_1_BUTTON_3 AT_TRANSLATED_SET_2_KEYBOARD_KEY_E
# PLAYER_1_BUTTON_4 AT_TRANSLATED_SET_2_KEYBOARD_KEY_R
# PLAYER_1_BUTTON_5 AT_TRANSLATED_SET_2_KEYBOARD_KEY_T
# PLAYER_1_BUTTON_6 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y
# PLAYER_1_BUTTON_7 AT_TRANSLATED_SET_2_KEYBOARD_KEY_I
# PLAYER_1_BUTTON_8 AT_TRANSLATED_SET_2_KEYBOARD_KEY_O
# PLAYER_2_BUTTON_START AT_TRANSLATED_SET_2_KEYBOARD_KEY_1
# PLAYER_2_BUTTON_SERVICE AT_TRANSLATED_SET_2_KEYBOARD_KEY_S
# PLAYER_2_BUTTON_UP AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP
# PLAYER_2_BUTTON_DOWN AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN
# PLAYER_2_BUTTON_LEFT AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT
# PLAYER_2_BUTTON_RIGHT AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT
# PLAYER_2_BUTTON_1 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q
# PLAYER_2_BUTTON_2 AT_TRANSLATED_SET_2_KEYBOARD_KEY_W
# PLAYER_2_BUTTON_3 AT_TRANSLATED_SET_2_KEYBOARD_KEY_E
# PLAYER_2_BUTTON_4 AT_TRANSLATED_SET_2_KEYBOARD_KEY_R
# PLAYER_2_BUTTON_5 AT_TRANSLATED_SET_2_KEYBOARD_KEY_T
# PLAYER_2_BUTTON_6 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y
# PLAYER_2_BUTTON_7 AT_TRANSLATED_SET_2_KEYBOARD_KEY_I
# PLAYER_2_BUTTON_8 AT_TRANSLATED_SET_2_KEYBOARD_KEY_O
# ANALOGUE_1 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_X
# ANALOGUE_2 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Y
# ANALOGUE_3 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Z
# ANALOGUE_4 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_RZ

View File

@ -1,34 +0,0 @@
# Supported Titles
## Games that work
These games have been loaded at some point using this software, but this doesn't mean they currently work or there are instructions on how to get them running.
Working is defined by getting into attract mode and running the game, but not necessarily controlling it.
| Game Name | Game ID | DVP | NVidia | Intel | AMD | Comments |
|---------------------------------|---------|-----|--------|-------|-----|------------------------------|
| 2 Step 2 Spicy | | | ✓ | | | |
| After Burner Climax | | | ✓ | | | |
| Ghost Squad Evolution | | | ✓ | | | Controls don't work properly |
| Harley Davidson | | | ✓ | | | |
| Hummer Extreme | | | ✓ | | | |
| Hummer | | | ✓ | | | |
| Let's Go Jungle | | | ✓ | | | |
| Let's Go Jungle Special | | | ✓ | | | |
| Outrun 2 SP SDX | | | ✓ | | | |
| R-Tuned | | | ✓ | | | |
| Race TV | | | ✓ | | | |
| Rambo | | | ✓ | | | |
| The House of the Dead 4 | | | ✓ | ✓ | | |
| The House of the Dead 4 Special | | | ✓ | ✓ | | |
| The House of the Dead Ex | | | ✓ | | | |
| Virtua Fighter 5 | | | ✓ | | | |
| Virtua Fighter 5 R | | | ✓ | | | |
| Virtua Fighter 5 FS | | | ✓ | | | |
| Initial D 4 | | | ✓ | | | |
| Initial D 5 | | | | | | Black Screen |
| Virtua Tennis 3 | | | ✓ | | | |
| Primevil | | | ✓ | | | |

View File

@ -1,71 +0,0 @@
# Windows Installation Instructions
Please note that this software is still in the alpha phase, and it's very unlikely any games will be fully playable.
## Requirements
- Windows 10 build 2004 or higher
- WSL2
- Ubuntu 22.04
## Building & Installation
Launch Ubuntu 22.04 and and reset the root password.
```
sudo passwd root
su root
```
Now that you're in the root user you can install the dependencies:
```
sudo dpkg --add-architecture i386
sudo apt update && apt list --upgradable && apt upgrade
sudo apt install wsl g++ mesa-utils cmake make-guile gcc-multilib xorg-dev libxmu6:i386 libstdc++5:i386 libopenal-dev:i386 freeglut3:i386 freeglut3-dev:i386 libglew-dev
```
Now you will need to build libalut (the audio library) from source:
```
git clone --recursive https://github.com/vancegroup/freealut.git
cd freealut
cmake . -DCMAKE_INSTALL_PREFIX:STRING="/usr" -DCMAKE_C_FLAGS:STRING="-m32 -O2"
make
make install
```
Now you should add yourself to the following groups.
```
sudo addgroup $USER dialout
sudo addgroup $USER input
```
Now you can clone and build the lindbergh loader repository.
```
cd
git clone https://github.com/bobbydilley/lindbergh-loader.git
cd lindbergh-loader
make
```
You should then see the 3 .so files produced in the `build` directory.
## Launching a game
You should copy the 3 files from the `lindbergh-loader/build` directory to the directory with the game elf in.
Then open powershell in windows and do the following steps.
```
cd C:\rom\hod4\elf
bash
cp ~/lindbergh-loader/build/* .
LD_PRELOAD=lindbergh.so LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./hod4M.elf
```
## Thanks
Thanks to dorminirko for the testing and writing of the original guide.

BIN
libs/libCg.so Executable file

Binary file not shown.

View File

@ -0,0 +1 @@
#include "libposixtime.h"

1159
src/libsegaapi/libsegaapi.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,220 +1,270 @@
#ifndef __SEGAAPI_H
#define __SEGAAPI_H
/* GUID Definitions */
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern const GUID name
DEFINE_GUID(EAXPROPERTYID_EAX40_SEGA_Custom, 0xa7feec3f, 0x2bfd, 0x4a40, 0x89, 0x1f, 0x74, 0x23, 0xe3, 0x8b, 0xac, 0x1f);
/* Return values */
#define SEGARESULT_FAILURE(_x) ((1 << 31) | 0xA000 | (_x))
#define SEGA_SUCCESS 0L
#define SEGA_ERROR_FAIL SEGARESULT_FAILURE(0)
#define SEGA_ERROR_BAD_POINTER SEGARESULT_FAILURE(3)
#define SEGA_ERROR_UNSUPPORTED SEGARESULT_FAILURE(5)
#define SEGA_ERROR_BAD_PARAM SEGARESULT_FAILURE(9)
#define SEGA_ERROR_INVALID_CHANNEL SEGARESULT_FAILURE(10)
#define SEGA_ERROR_INVALID_SEND SEGARESULT_FAILURE(11)
#define SEGA_ERROR_PLAYING SEGARESULT_FAILURE(12)
#define SEGA_ERROR_NO_RESOURCES SEGARESULT_FAILURE(13)
#define SEGA_ERROR_BAD_CONFIG SEGARESULT_FAILURE(14)
#define SEGA_ERROR_BAD_HANDLE SEGARESULT_FAILURE(18)
#define SEGA_ERROR_BAD_SAMPLERATE SEGARESULT_FAILURE(28)
#define SEGA_ERROR_OUT_OF_MEMORY SEGARESULT_FAILURE(31)
#define SEGA_ERROR_INIT_FAILED SEGARESULT_FAILURE(39)
/* Values used in various functions */
#define SYNTH_BUFFER 0x00000001
#define ALLOC_USER_MEM 0x00000002
#define USE_MAPPED_MEM 0x00000003
#define UNSIGNED_8PCM 0x0004
#define SIGNED_16PCM 0x0020
#define VOL_MAX 0xFFFFFFFF
#define P_MINIMUM 0
#define P_MAXIMUM 0xFFFFFFFF
#define UNUSED_SEND 0xFFFF0001
typedef enum
{
STEREO_RETURN_FX2 = 0,
STEREO_RETURN_FX3 = 1
} SegaProperty;
typedef enum
{
RESOURCE_STOLEN = 0,
NOTIFY = 2
} CallbackMessage;
typedef enum
{
PLAYBACK_STATUS_STOP,
PLAYBACK_STATUS_ACTIVE,
PLAYBACK_STATUS_PAUSE,
PLAYBACK_STATUS_INVALID = -1
} PlaybackStatus;
typedef struct
{
unsigned int dwSampleRate;
unsigned int dwSampleFormat;
unsigned int byNumChans;
} OutputFormat;
typedef struct
{
unsigned int dwSize;
unsigned int dwOffset;
void *hBufferHdr;
} MapData;
typedef struct
{
unsigned int dwPriority;
unsigned int dwSampleRate;
unsigned int dwSampleFormat;
unsigned int byNumChans;
unsigned int dwReserved;
void *hUserData;
MapData mapData;
} BufferConfig;
typedef enum Routing
{
UNUSED_PORT = UNUSED_SEND,
FRONT_LEFT_PORT = 0,
FRONT_RIGHT_PORT = 1,
FRONT_CENTER_PORT = 2,
LFE_PORT = 3,
REAR_LEFT_PORT = 4,
REAR_RIGHT_PORT = 5,
FXSLOT0_PORT = 10,
FXSLOT1_PORT = 11,
FXSLOT2_PORT = 12,
FXSLOT3_PORT = 13
} Routing;
typedef enum
{
SPDIFOUT_44_1KHZ = 0,
SPDIFOUT_48KHZ,
SPDIFOUT_96KHZ
} SPDIFOutputSampleRate;
typedef enum SoundBoardIO
{
OUT_FRONT_LEFT = 0,
OUT_FRONT_RIGHT = 1,
OUT_FRONT_CENTER = 2,
OUT_LFE_PORT = 3,
OUT_REAR_LEFT = 4,
OUT_REAR_RIGHT = 5,
OUT_OPTICAL_LEFT = 10,
OUT_OPTICAL_RIGHT = 11,
IN_LINEIN_LEFT = 20,
IN_LINEIN_RIGHT = 21
} SoundBoardIO;
typedef enum SynthParams
{
ATTENUATION,
PITCH,
FILTER_CUTOFF,
FILTER_Q,
DELAY_VOL_ENV,
ATTACK_VOL_ENV,
HOLD_VOL_ENV,
DECAY_VOL_ENV,
SUSTAIN_VOL_ENV,
RELEASE_VOL_ENV,
DELAY_MOD_ENV,
ATTACK_MOD_ENV,
HOLD_MOD_ENV,
DECAY_MOD_ENV,
SUSTAIN_MOD_ENV,
RELEASE_MOD_ENV,
DELAY_MOD_LFO,
FREQ_MOD_LFO,
DELAY_VIB_LFO,
FREQ_VIB_LFO,
MOD_LFO_TO_PITCH,
VIB_LFO_TO_PITCH,
MOD_LFO_TO_FILTER_CUTOFF,
MOD_LFO_TO_ATTENUATION,
MOD_ENV_TO_PITCH,
MOD_ENV_TO_FILTER_CUTOFF
} SynthParams;
typedef struct SynthParamSetExt
{
SynthParams param;
int lPARWValue;
} SynthParamSet;
int SEGAAPI_Play(void *hHandle);
int SEGAAPI_Pause(void *hHandle);
int SEGAAPI_Stop(void *hHandle);
int SEGAAPI_PlayWithSetup(void *hHandle);
PlaybackStatus SEGAAPI_GetPlaybackStatus(void *hHandle);
int SEGAAPI_SetFormat(void *hHandle, OutputFormat *pFormat);
int SEGAAPI_GetFormat(void *hHandle, OutputFormat *pFormat);
int SEGAAPI_SetSampleRate(void *hHandle, unsigned int dwSampleRate);
unsigned int SEGAAPI_GetSampleRate(void *hHandle);
int SEGAAPI_SetPriority(void *hHandle, unsigned int dwPriority);
unsigned int SEGAAPI_GetPriority(void *hHandle);
int SEGAAPI_SetUserData(void *hHandle, void *hUserData);
void *SEGAAPI_GetUserData(void *hHandle);
int SEGAAPI_SetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend, Routing dwDest);
Routing SEGAAPI_GetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend);
int SEGAAPI_SetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend, unsigned int dwLevel);
unsigned int SEGAAPI_GetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend);
int SEGAAPI_SetChannelVolume(void *hHandle, unsigned int dwChannel, unsigned int dwVolume);
unsigned int SEGAAPI_GetChannelVolume(void *hHandle, unsigned int dwChannel);
int SEGAAPI_SetPlaybackPosition(void *hHandle, unsigned int dwPlaybackPos);
unsigned int SEGAAPI_GetPlaybackPosition(void *hHandle);
int SEGAAPI_SetNotificationFrequency(void *hHandle, unsigned int dwFrameCount);
int SEGAAPI_SetNotificationPoint(void *hHandle, unsigned int dwBufferOffset);
int SEGAAPI_ClearNotificationPoint(void *hHandle, unsigned int dwBufferOffset);
int SEGAAPI_SetStartLoopOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetStartLoopOffset(void *hHandle);
int SEGAAPI_SetEndLoopOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetEndLoopOffset(void *hHandle);
int SEGAAPI_SetEndOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetEndOffset(void *hHandle);
int SEGAAPI_SetLoopState(void *hHandle, int bDoContinuousLooping);
int SEGAAPI_GetLoopState(void *hHandle);
int SEGAAPI_UpdateBuffer(void *hHandle, unsigned int dwStartOffset, unsigned int dwLength);
int SEGAAPI_SetSynthParam(void *hHandle, SynthParams param, int lPARWValue);
int SEGAAPI_GetSynthParam(void *hHandle, SynthParams param);
int SEGAAPI_SetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams);
int SEGAAPI_GetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams);
int SEGAAPI_SetReleaseState(void *hHandle, int bSet);
typedef void (*BufferCallback)(void *hHandle, CallbackMessage message);
int SEGAAPI_CreateBuffer(BufferConfig *pConfig, BufferCallback pCallback, unsigned int dwFlags, void **phHandle);
int SEGAAPI_DestroyBuffer(void *hHandle);
int SEGAAPI_SetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize);
int SEGAAPI_GetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize);
int SEGAAPI_SetSPDIFOutChannelStatus(unsigned int dwChannelStatus, unsigned int dwExtChannelStatus);
int SEGAAPI_GetSPDIFOutChannelStatus(unsigned int *pdwChannelStatus, unsigned int *pdwExtChannelStatus);
int SEGAAPI_SetSPDIFOutSampleRate(SPDIFOutputSampleRate dwSamplingRate);
SPDIFOutputSampleRate SEGAAPI_GetSPDIFOutSampleRate(void);
int SEGAAPI_SetSPDIFOutChannelRouting(unsigned int dwChannel, Routing dwSource);
Routing SEGAAPI_GetSPDIFOutChannelRouting(unsigned int dwChannel);
int SEGAAPI_SetIOVolume(SoundBoardIO dwPhysIO, unsigned int dwVolume);
unsigned int SEGAAPI_GetIOVolume(SoundBoardIO dwPhysIO);
void SEGAAPI_SetLastStatus(int LastStatus);
int SEGAAPI_GetLastStatus(void);
int SEGAAPI_Reset(void);
int SEGAAPI_Init(void);
int SEGAAPI_Exit(void);
#endif /* __SEGAAPI_H */
#ifndef __SEGAAPI_H
#define __SEGAAPI_H
/* GUID Definitions */
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern const GUID name
DEFINE_GUID(EAXPROPERTYID_EAX40_SEGA_Custom, 0xa7feec3f, 0x2bfd, 0x4a40, 0x89, 0x1f, 0x74, 0x23, 0xe3, 0x8b, 0xac, 0x1f);
GUID EAX_NULL_GUID;
GUID EAX_FREQUENCYSHIFTER_EFFECT;
GUID EAX_ECHO_EFFECT;
GUID EAX_REVERB_EFFECT;
GUID EAX_EQUALIZER_EFFECT;
GUID EAX_DISTORTION_EFFECT;
GUID EAX_AGCCOMPRESSOR_EFFECT;
GUID EAX_PITCHSHIFTER_EFFECT;
GUID EAX_FLANGER_EFFECT;
GUID EAX_VOCALMORPHER_EFFECT;
GUID EAX_AUTOWAH_EFFECT;
GUID EAX_RINGMODULATOR_EFFECT;
GUID EAX_CHORUS_EFFECT;
GUID EAXPROPERTYID_EAX40_FXSlot0;
GUID EAXPROPERTYID_EAX40_FXSlot1;
GUID EAXPROPERTYID_EAX40_FXSlot2;
GUID EAXPROPERTYID_EAX40_FXSlot3;
/* Return values */
#define SEGARESULT_FAILURE(_x) ((1 << 31) | 0xA000 | (_x))
#define SEGA_SUCCESS 0L
#define SEGA_ERROR_FAIL SEGARESULT_FAILURE(0)
#define SEGA_ERROR_BAD_POINTER SEGARESULT_FAILURE(3)
#define SEGA_ERROR_UNSUPPORTED SEGARESULT_FAILURE(5)
#define SEGA_ERROR_BAD_PARAM SEGARESULT_FAILURE(9)
#define SEGA_ERROR_INVALID_CHANNEL SEGARESULT_FAILURE(10)
#define SEGA_ERROR_INVALID_SEND SEGARESULT_FAILURE(11)
#define SEGA_ERROR_PLAYING SEGARESULT_FAILURE(12)
#define SEGA_ERROR_NO_RESOURCES SEGARESULT_FAILURE(13)
#define SEGA_ERROR_BAD_CONFIG SEGARESULT_FAILURE(14)
#define SEGA_ERROR_BAD_HANDLE SEGARESULT_FAILURE(18)
#define SEGA_ERROR_BAD_SAMPLERATE SEGARESULT_FAILURE(28)
#define SEGA_ERROR_OUT_OF_MEMORY SEGARESULT_FAILURE(31)
#define SEGA_ERROR_INIT_FAILED SEGARESULT_FAILURE(39)
/* Values used in various functions */
#define SYNTH_BUFFER 0x00000001
#define ALLOC_USER_MEM 0x00000002
#define USE_MAPPED_MEM 0x00000004
#define UNSIGNED_8PCM 0x0004
#define SIGNED_16PCM 0x0020
#define VOL_MAX 0xFFFFFFFF
#define P_MINIMUM 0
#define P_MAXIMUM 0xFFFFFFFF
#define UNUSED_SEND 0xFFFF0001
typedef enum
{
STEREO_RETURN_FX2 = 0,
STEREO_RETURN_FX3 = 1
} SegaProperty;
typedef enum
{
RESOURCE_STOLEN = 0,
NOTIFY = 2
} CallbackMessage;
typedef enum
{
PLAYBACK_STATUS_STOP,
PLAYBACK_STATUS_ACTIVE,
PLAYBACK_STATUS_PAUSE,
PLAYBACK_STATUS_INVALID = -1
} PlaybackStatus;
typedef struct
{
unsigned int dwSampleRate;
unsigned int dwSampleFormat;
unsigned int byNumChans;
} OutputFormat;
typedef struct
{
unsigned int dwSize;
unsigned int dwOffset;
void *hBufferHdr;
} MapData;
typedef struct
{
unsigned int dwPriority;
unsigned int dwSampleRate;
unsigned int dwSampleFormat;
unsigned int byNumChans;
unsigned int dwReserved;
void *hUserData;
MapData mapData;
} BufferConfig;
typedef enum Routing
{
UNUSED_PORT = UNUSED_SEND,
FRONT_LEFT_PORT = 0,
FRONT_RIGHT_PORT = 1,
FRONT_CENTER_PORT = 2,
LFE_PORT = 3,
REAR_LEFT_PORT = 4,
REAR_RIGHT_PORT = 5,
FXSLOT0_PORT = 10,
FXSLOT1_PORT = 11,
FXSLOT2_PORT = 12,
FXSLOT3_PORT = 13
} Routing;
typedef enum
{
SPDIFOUT_44_1KHZ = 0,
SPDIFOUT_48KHZ,
SPDIFOUT_96KHZ
} SPDIFOutputSampleRate;
typedef enum SoundBoardIO
{
OUT_FRONT_LEFT = 0,
OUT_FRONT_RIGHT = 1,
OUT_FRONT_CENTER = 2,
OUT_LFE_PORT = 3,
OUT_REAR_LEFT = 4,
OUT_REAR_RIGHT = 5,
OUT_OPTICAL_LEFT = 10,
OUT_OPTICAL_RIGHT = 11,
IN_LINEIN_LEFT = 20,
IN_LINEIN_RIGHT = 21
} SoundBoardIO;
typedef enum SynthParams
{
ATTENUATION,
PITCH,
FILTER_CUTOFF,
FILTER_Q,
DELAY_VOL_ENV,
ATTACK_VOL_ENV,
HOLD_VOL_ENV,
DECAY_VOL_ENV,
SUSTAIN_VOL_ENV,
RELEASE_VOL_ENV,
DELAY_MOD_ENV,
ATTACK_MOD_ENV,
HOLD_MOD_ENV,
DECAY_MOD_ENV,
SUSTAIN_MOD_ENV,
RELEASE_MOD_ENV,
DELAY_MOD_LFO,
FREQ_MOD_LFO,
DELAY_VIB_LFO,
FREQ_VIB_LFO,
MOD_LFO_TO_PITCH,
VIB_LFO_TO_PITCH,
MOD_LFO_TO_FILTER_CUTOFF,
MOD_LFO_TO_ATTENUATION,
MOD_ENV_TO_PITCH,
MOD_ENV_TO_FILTER_CUTOFF
} SynthParams;
typedef enum VoiceIOControls
{
SET_START_LOOP_OFFSET = 0x100,
SET_END_LOOP_OFFSET,
SET_END_OFFSET,
SET_PLAY_POSITION,
SET_LOOP_STATE,
SET_NOTIFICATION_POINT,
CLEAR_NOTIFICATION_POINT,
SET_NOTIFICATION_FREQUENCY
} VoiceIOControls;
typedef struct SynthParamSetExt
{
SynthParams param;
int lPARWValue;
} SynthParamSet;
typedef struct SendRouteParamSetExt
{
unsigned int dwChannel;
unsigned int dwSend;
Routing dwDest;
} SendRouteParamSet;
typedef struct SendLevelParamSetExt
{
unsigned int dwChannel;
unsigned int dwSend;
unsigned int dwLevel;
} SendLevelParamSet;
typedef struct VoiceParamSetExt
{
VoiceIOControls VoiceIoctl;
unsigned int dwParam1;
unsigned int dwParam2;
} VoiceParamSet;
int SEGAAPI_Play(void *hHandle);
int SEGAAPI_Pause(void *hHandle);
int SEGAAPI_Stop(void *hHandle);
int SEGAAPI_PlayWithSetup(void* hHandle, unsigned int dwNumSendRouteParams, SendRouteParamSet* pSendRouteParams, unsigned int dwNumSendLevelParams, SendLevelParamSet* pSendLevelParams, unsigned int dwNumVoiceParams, VoiceParamSet* pVoiceParams, unsigned int dwNumSynthParams, SynthParamSet* pSynthParams);
PlaybackStatus SEGAAPI_GetPlaybackStatus(void *hHandle);
int SEGAAPI_SetFormat(void *hHandle, OutputFormat *pFormat);
int SEGAAPI_GetFormat(void *hHandle, OutputFormat *pFormat);
int SEGAAPI_SetSampleRate(void *hHandle, unsigned int dwSampleRate);
unsigned int SEGAAPI_GetSampleRate(void *hHandle);
int SEGAAPI_SetPriority(void *hHandle, unsigned int dwPriority);
unsigned int SEGAAPI_GetPriority(void *hHandle);
int SEGAAPI_SetUserData(void *hHandle, void *hUserData);
void *SEGAAPI_GetUserData(void *hHandle);
int SEGAAPI_SetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend, Routing dwDest);
Routing SEGAAPI_GetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend);
int SEGAAPI_SetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend, unsigned int dwLevel);
unsigned int SEGAAPI_GetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend);
int SEGAAPI_SetChannelVolume(void *hHandle, unsigned int dwChannel, unsigned int dwVolume);
unsigned int SEGAAPI_GetChannelVolume(void *hHandle, unsigned int dwChannel);
int SEGAAPI_SetPlaybackPosition(void *hHandle, unsigned int dwPlaybackPos);
unsigned int SEGAAPI_GetPlaybackPosition(void *hHandle);
int SEGAAPI_SetNotificationFrequency(void *hHandle, unsigned int dwFrameCount);
int SEGAAPI_SetNotificationPoint(void *hHandle, unsigned int dwBufferOffset);
int SEGAAPI_ClearNotificationPoint(void *hHandle, unsigned int dwBufferOffset);
int SEGAAPI_SetStartLoopOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetStartLoopOffset(void *hHandle);
int SEGAAPI_SetEndLoopOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetEndLoopOffset(void *hHandle);
int SEGAAPI_SetEndOffset(void *hHandle, unsigned int dwOffset);
unsigned int SEGAAPI_GetEndOffset(void *hHandle);
int SEGAAPI_SetLoopState(void *hHandle, int bDoContinuousLooping);
int SEGAAPI_GetLoopState(void *hHandle);
int SEGAAPI_UpdateBuffer(void *hHandle, unsigned int dwStartOffset, unsigned int dwLength);
int SEGAAPI_SetSynthParam(void *hHandle, SynthParams param, int lPARWValue);
int SEGAAPI_GetSynthParam(void *hHandle, SynthParams param);
int SEGAAPI_SetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams);
int SEGAAPI_GetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams);
int SEGAAPI_SetReleaseState(void *hHandle, int bSet);
typedef void (*BufferCallback)(void *hHandle, CallbackMessage message);
int SEGAAPI_CreateBuffer(BufferConfig *pConfig, BufferCallback pCallback, unsigned int dwFlags, void **phHandle);
int SEGAAPI_DestroyBuffer(void *hHandle);
int SEGAAPI_SetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize);
int SEGAAPI_GetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize);
int SEGAAPI_SetSPDIFOutChannelStatus(unsigned int dwChannelStatus, unsigned int dwExtChannelStatus);
int SEGAAPI_GetSPDIFOutChannelStatus(unsigned int *pdwChannelStatus, unsigned int *pdwExtChannelStatus);
int SEGAAPI_SetSPDIFOutSampleRate(SPDIFOutputSampleRate dwSamplingRate);
SPDIFOutputSampleRate SEGAAPI_GetSPDIFOutSampleRate(void);
int SEGAAPI_SetSPDIFOutChannelRouting(unsigned int dwChannel, Routing dwSource);
Routing SEGAAPI_GetSPDIFOutChannelRouting(unsigned int dwChannel);
int SEGAAPI_SetIOVolume(SoundBoardIO dwPhysIO, unsigned int dwVolume);
unsigned int SEGAAPI_GetIOVolume(SoundBoardIO dwPhysIO);
void SEGAAPI_SetLastStatus(int LastStatus);
int SEGAAPI_GetLastStatus(void);
int SEGAAPI_Reset(void);
int SEGAAPI_Init(void);
int SEGAAPI_Exit(void);
#endif /* __SEGAAPI_H */

View File

@ -1,825 +0,0 @@
#define TSF_IMPLEMENTATION
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
#include <AL/alut.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "segaapi.h"
#include "tsf.h"
// #define DEBUG_OUTPUT
const GUID EAX_NULL_GUID;
const GUID EAX_FREQUENCYSHIFTER_EFFECT;
const GUID EAX_ECHO_EFFECT;
const GUID EAX_REVERB_EFFECT;
const GUID EAX_EQUALIZER_EFFECT;
const GUID EAX_DISTORTION_EFFECT;
const GUID EAX_AGCCOMPRESSOR_EFFECT;
const GUID EAX_PITCHSHIFTER_EFFECT;
const GUID EAX_FLANGER_EFFECT;
const GUID EAX_VOCALMORPHER_EFFECT;
const GUID EAX_AUTOWAH_EFFECT;
const GUID EAX_RINGMODULATOR_EFFECT;
const GUID EAX_CHORUS_EFFECT;
const GUID EAXPROPERTYID_EAX40_FXSlot0;
const GUID EAXPROPERTYID_EAX40_FXSlot1;
const GUID EAXPROPERTYID_EAX40_FXSlot2;
const GUID EAXPROPERTYID_EAX40_FXSlot3;
typedef struct
{
// SEGA API Parts
void *userData;
BufferCallback callback;
bool synthesizer;
bool loop;
unsigned int channels;
unsigned int startLoop;
unsigned int endLoop;
unsigned int endOffset;
unsigned int sampleRate;
unsigned int sampleFormat;
uint8_t *data;
size_t size;
bool playing;
bool paused;
// OpenAL Parts
ALuint alBuffer;
ALuint alSource;
// TinySoundFont Parts
tsf *synth;
struct tsf_region *region;
} SEGAContext;
#ifdef DEBUG_OUTPUT
void dbgPrint(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
}
#else
void dbgPrint(const char *format, ...)
{
return;
}
#endif
/**
* Returns the OpenAL Format Enum from the sampleFormat and channels
* of the SEGA API.
*
* @param sampleFormat SEGA API Sample Format
* @param channels Amount of channels to use
* @returns The OpenAL Format
*/
ALenum getAlFormat(unsigned int sampleFormat, unsigned int channels)
{
ALenum alFormat = -1;
switch (sampleFormat)
{
case UNSIGNED_8PCM: /* Unsigned (offset 128) 8-bit PCM */
switch (channels)
{
case 1:
alFormat = AL_MONO8_SOFT;
break;
case 2:
alFormat = AL_STEREO8_SOFT;
break;
default:
break;
}
break;
case SIGNED_16PCM: /* Signed 16-bit PCM */
switch (channels)
{
case 1:
alFormat = AL_MONO16_SOFT;
break;
case 2:
alFormat = AL_STEREO16_SOFT;
break;
default:
break;
}
default:
break;
}
if (alFormat == -1)
{
printf("SEGAAPI Fatal Error: Unknown format - 0x%X with %d channels!\n", sampleFormat, channels);
abort();
}
return alFormat;
}
static void updateBufferData(SEGAContext *context, unsigned int offset, size_t length)
{
alSourcei(context->alSource, AL_BUFFER, AL_NONE);
alBufferData(context->alBuffer, getAlFormat(context->sampleFormat, context->channels), context->data, context->size, context->sampleRate);
alSourcei(context->alSource, AL_BUFFER, context->alBuffer);
}
static void resetBuffer(SEGAContext *context)
{ // printf("%s %d\n", __func__, __LINE__);
// * - Send Routing
// * - for 1 channel buffer, channel is routed to Front-Left and Front-Right.
// * - for 2 channel buffer, channel 0 is routed Front-Left, channel 1 is routed Front-Right
// * - Send Levels are set to 0 (infinite attenuation)
// * - Channel Volume is set to 0xFFFFFFFF (no attenuation)
// * - No notification.
// * - StartLoopOffset is set to 0.
// * - EndLoopOffset and EndOffset are set to pConfig->mapdata.dwSize.
// * - No loop.
context->startLoop = 0;
context->endOffset = context->size;
context->endLoop = context->size;
context->loop = false;
context->paused = false;
tsf *res = (tsf *)TSF_MALLOC(sizeof(tsf));
TSF_MEMSET(res, 0, sizeof(tsf));
res->presetNum = 0;
res->outSampleRate = context->sampleRate;
context->synth = res;
struct tsf_region *region = malloc(sizeof(struct tsf_region));
memset(region, 0, sizeof(struct tsf_region));
tsf_region_clear(region, 0);
region->ampenv.delay = 0;
region->ampenv.hold = 300.0f;
region->ampenv.attack = 0;
region->ampenv.decay = 0;
region->ampenv.release = 0;
region->ampenv.sustain = 0;
context->region = region;
alSourcei(context->alSource, AL_BUFFER, AL_NONE);
alSourcei(context->alSource, AL_BYTE_OFFSET, 0);
alSourceStop(context->alSource);
}
int SEGAAPI_Play(void *hHandle)
{
dbgPrint("SEGAAPI_Play() 0x%x", hHandle);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_PARAM;
alSourcePlay(context->alSource);
return SEGA_SUCCESS;
}
int SEGAAPI_Pause(void *hHandle)
{
dbgPrint("SEGAAPI_Pause() 0x%x", hHandle);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_PARAM;
alSourcePause(context->alSource);
return SEGA_SUCCESS;
}
int SEGAAPI_Stop(void *hHandle)
{
dbgPrint("SEGAAPI_Stop() 0x%x", hHandle);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_PARAM;
alSourceStop(context->alSource);
return SEGA_SUCCESS;
}
int SEGAAPI_PlayWithSetup(void *hHandle)
{
dbgPrint("SEGAAPI_PlayWithSetup() 0x%x", hHandle);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_PARAM;
alSourcePlay(context->alSource);
return SEGA_ERROR_UNSUPPORTED;
}
PlaybackStatus SEGAAPI_GetPlaybackStatus(void *hHandle)
{
dbgPrint("SEGAAPI_GetPlaybackStatus() 0x%x", hHandle);
SEGAContext *context = hHandle;
if (context == NULL)
return PLAYBACK_STATUS_INVALID;
ALint state;
alGetSourcei(context->alSource, AL_SOURCE_STATE, &state);
switch (state)
{
case AL_PLAYING:
return PLAYBACK_STATUS_ACTIVE;
case AL_PAUSED:
return PLAYBACK_STATUS_PAUSE;
case AL_INITIAL:
return PLAYBACK_STATUS_ACTIVE;
case AL_STOPPED:
return PLAYBACK_STATUS_STOP;
default:
return PLAYBACK_STATUS_INVALID;
}
return PLAYBACK_STATUS_INVALID;
}
int SEGAAPI_SetFormat(void *hHandle, OutputFormat *pFormat)
{
dbgPrint("SEGAAPI_SetFormat() 0x%x", hHandle);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_GetFormat(void *hHandle, OutputFormat *pFormat)
{
dbgPrint("SEGAAPI_GetFormat() 0x%x", hHandle);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetSampleRate(void *hHandle, unsigned int dwSampleRate)
{
dbgPrint("SEGAAPI_SetSampleRate() 0x%x 0x%x", hHandle, dwSampleRate);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->sampleRate = dwSampleRate;
updateBufferData(context, -1, -1);
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetSampleRate(void *hHandle)
{
dbgPrint("SEGAAPI_GetSampleRate() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
return context->sampleRate;
}
int SEGAAPI_SetPriority(void *hHandle, unsigned int dwPriority)
{
dbgPrint("SEGAAPI_SetPriority() 0x%x 0x%x", hHandle, dwPriority);
return SEGA_ERROR_UNSUPPORTED;
}
unsigned int SEGAAPI_GetPriority(void *hHandle)
{
dbgPrint("SEGAAPI_GetPriority() 0x%x", hHandle);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetUserData(void *hHandle, void *hUserData)
{
dbgPrint("SEGAAPI_SetUserData() 0x%x 0x%x", hHandle, hUserData);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->userData = hUserData;
return SEGA_SUCCESS;
}
void *SEGAAPI_GetUserData(void *hHandle)
{
dbgPrint("SEGAAPI_GetPriority() 0x%x", hHandle);
if (hHandle == NULL)
return NULL;
SEGAContext *context = hHandle;
return context->userData;
}
int SEGAAPI_SetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend, Routing dwDest)
{
dbgPrint("SEGAAPI_SetSendRouting() 0x%x 0x%x 0x%x 0x%x", hHandle, dwChannel, dwSend, dwDest);
return SEGA_SUCCESS;
}
Routing SEGAAPI_GetSendRouting(void *hHandle, unsigned int dwChannel, unsigned int dwSend)
{
dbgPrint("SEGAAPI_GetSendRouting() 0x%x 0x%x 0x%x", hHandle, dwChannel, dwSend);
return UNUSED_PORT;
}
int SEGAAPI_SetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend, unsigned int dwLevel)
{
dbgPrint("SEGAAPI_SetSendLevel() 0x%x 0x%x 0x%x 0x%x", hHandle, dwChannel, dwSend, dwLevel);
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetSendLevel(void *hHandle, unsigned int dwChannel, unsigned int dwSend)
{
dbgPrint("SEGAAPI_GetSendLevel() 0x%x 0x%x 0x%x", hHandle, dwChannel, dwSend);
return SEGA_SUCCESS;
}
int SEGAAPI_SetChannelVolume(void *hHandle, unsigned int dwChannel, unsigned int dwVolume)
{
dbgPrint("SEGAAPI_SetChannelVolume() 0x%x 0x%x 0x%x", hHandle, dwChannel, dwVolume);
return SEGA_ERROR_UNSUPPORTED;
}
unsigned int SEGAAPI_GetChannelVolume(void *hHandle, unsigned int dwChannel)
{
dbgPrint("SEGAAPI_GetChannelVolume() 0x%x 0x%x", hHandle, dwChannel);
return 0;
}
int SEGAAPI_SetPlaybackPosition(void *hHandle, unsigned int dwPlaybackPos)
{
dbgPrint("SEGAAPI_SetPlaybackPosition() 0x%x 0x%x", hHandle, dwPlaybackPos);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
alSourcei(context->alSource, AL_BYTE_OFFSET, dwPlaybackPos);
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetPlaybackPosition(void *hHandle)
{
dbgPrint("SEGAAPI_GetPlaybackPosition() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
ALint position;
alGetSourcei(context->alSource, AL_BYTE_OFFSET, &position);
return position;
}
int SEGAAPI_SetNotificationFrequency(void *hHandle, unsigned int dwFrameCount)
{
dbgPrint("SEGAAPI_SetNotificationFrequency() 0x%x 0x%x", hHandle, dwFrameCount);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetNotificationPoint(void *hHandle, unsigned int dwBufferOffset)
{
dbgPrint("SEGAAPI_SetNotificationPoint() 0x%x 0x%x", hHandle, dwBufferOffset);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_ClearNotificationPoint(void *hHandle, unsigned int dwBufferOffset)
{
dbgPrint("SEGAAPI_ClearNotificationPoint() 0x%x 0x%x", hHandle, dwBufferOffset);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetStartLoopOffset(void *hHandle, unsigned int dwOffset)
{
dbgPrint("SEGAAPI_SetStartLoopOffset() 0x%x 0x%x", hHandle, dwOffset);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->startLoop = dwOffset;
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetStartLoopOffset(void *hHandle)
{
dbgPrint("SEGAAPI_GetStartLoopOffset() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
return context->startLoop;
}
int SEGAAPI_SetEndLoopOffset(void *hHandle, unsigned int dwOffset)
{
dbgPrint("SEGAAPI_SetEndLoopOffset() 0x%x 0x%x", hHandle, dwOffset);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->endLoop = dwOffset;
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetEndLoopOffset(void *hHandle)
{
dbgPrint("SEGAAPI_GetEndLoopOffset() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
return context->endLoop;
}
int SEGAAPI_SetEndOffset(void *hHandle, unsigned int dwOffset)
{
dbgPrint("SEGAAPI_SetEndOffset() 0x%x 0x%x", hHandle, dwOffset);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->endOffset = dwOffset;
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetEndOffset(void *hHandle)
{
dbgPrint("SEGAAPI_GetEndOffset() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
return context->endOffset;
}
int SEGAAPI_SetLoopState(void *hHandle, int loop)
{
dbgPrint("SEGAAPI_SetLoopState() 0x%x 0x%x", hHandle, loop);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
context->loop = loop;
return SEGA_SUCCESS;
}
int SEGAAPI_GetLoopState(void *hHandle)
{
dbgPrint("SEGAAPI_GetLoopState() 0x%x", hHandle);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
return context->loop;
}
int SEGAAPI_UpdateBuffer(void *hHandle, unsigned int dwStartOffset, unsigned int dwLength)
{
dbgPrint("SEGAAPI_UpdateBuffer() 0x%x 0x%x 0x%x", hHandle, dwStartOffset, dwLength);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
updateBufferData(context, dwStartOffset, dwLength);
return SEGA_SUCCESS;
}
int SEGAAPI_SetSynthParam(void *hHandle, SynthParams param, int lPARWValue)
{
dbgPrint("SEGAAPI_SetSynthParam() 0x%x 0x%x 0x%x", hHandle, param, lPARWValue);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_PARAM;
switch (param)
{
case ATTENUATION:
{
float volume = tsf_decibelsToGain(0.0f - lPARWValue / 10.0f);
alListenerf(AL_GAIN, volume);
// buffer->xaVoice->SetVolume(volume);
dbgPrint("SEGAAPI_SetSynthParam() HAVP_ATTENUATION gain: %f dB: %d", volume, lPARWValue);
}
break;
case PITCH:
{
float semiTones = lPARWValue / 100.0f;
// freqRatio = XAudio2SemitonesToFrequencyRatio(semiTones);
// http://www-personal.umich.edu/~bazald/l/api/_x_audio2_8h_source.html
float freqRatio = powf(2.0f, semiTones / 12.0f);
// buffer->xaVoice->SetFrequencyRatio(freqRatio);
alSourcef(context->alSource, AL_PITCH, freqRatio);
dbgPrint("SEGAAPI_SetSynthParam() HAVP_PITCH hHandle: %08X semitones: %f freqRatio: %f", hHandle, semiTones, freqRatio);
}
break;
default:
dbgPrint("SEGAAPI_SetSynthParam() unsupported param: 0x%x", param);
}
return SEGA_SUCCESS;
}
int SEGAAPI_GetSynthParam(void *hHandle, SynthParams param)
{
dbgPrint("SEGAAPI_GetSynthParam() 0x%x 0x%x", hHandle, param);
return 0;
}
int SEGAAPI_SetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams)
{
dbgPrint("SEGAAPI_SetSynthParamMultiple() 0x%x 0x%x 0x%x", hHandle, dwNumParams, pSynthParams);
SEGAContext *context = hHandle;
if (context == NULL)
return SEGA_ERROR_BAD_HANDLE;
for (int i = 0; i < dwNumParams; i++)
{
SEGAAPI_SetSynthParam(hHandle, pSynthParams[i].param, pSynthParams[i].lPARWValue);
}
return SEGA_SUCCESS;
}
int SEGAAPI_GetSynthParamMultiple(void *hHandle, unsigned int dwNumParams, SynthParamSet *pSynthParams)
{
dbgPrint("SEGAAPI_GetSynthParamMultiple() 0x%x 0x%x 0x%x", hHandle, dwNumParams, pSynthParams);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetReleaseState(void *hHandle, int enterReleasePhase)
{
dbgPrint("SEGAAPI_SetReleaseState() 0x%x 0x%x", hHandle, enterReleasePhase);
if (hHandle == NULL)
return SEGA_ERROR_BAD_HANDLE;
SEGAContext *context = hHandle;
if (!enterReleasePhase)
return SEGA_SUCCESS;
context->playing = false;
alSourceStop(context->alSource);
return SEGA_SUCCESS;
}
int SEGAAPI_CreateBuffer(BufferConfig *pConfig, BufferCallback pCallback, unsigned int dwFlags, void **phHandle)
{
dbgPrint("SEGAAPI_CreateBuffer() 0x%x 0x%x 0x%x 0x%x", pConfig, pCallback, dwFlags, phHandle);
if ((phHandle == NULL) || (pConfig == NULL))
{
dbgPrint("SEGAAPI_CreateBuffer() SEGA_ERROR_BAD_POINTER");
return SEGA_ERROR_BAD_POINTER;
}
SEGAContext *context = malloc(sizeof(SEGAContext));
if (context == NULL)
{
dbgPrint("SEGAAPI_CreateBuffer() SEGA_ERROR_OUT_OF_MEMORY");
return SEGA_ERROR_OUT_OF_MEMORY;
}
// dbgPrint("SEGAAPI_CreateBuffer() allocated %i bytes",sizeof(SEGAContext));
context->playing = false;
context->callback = pCallback;
context->synthesizer = dwFlags & SYNTH_BUFFER;
context->sampleRate = pConfig->dwSampleRate;
context->sampleFormat = pConfig->dwSampleFormat;
context->channels = pConfig->byNumChans;
context->userData = pConfig->hUserData;
context->size = pConfig->mapData.dwSize;
pConfig->mapData.dwOffset = 0;
// can't have all 3 types at once - sanity check
if ((dwFlags & 0x06) == 0x06)
{
dbgPrint("SEGAAPI_CreateBuffer() SEGA_ERROR_BAD_PARAM");
free(context);
return SEGA_ERROR_BAD_PARAM;
}
// The caller allocates the buffer memory
if (dwFlags & ALLOC_USER_MEM)
{
context->data = pConfig->mapData.hBufferHdr;
dbgPrint("SEGAAPI_CreateBuffer() user memory 0x%x", context->data);
}
// We should reuse mapped memory for the buffer
else if (dwFlags & USE_MAPPED_MEM)
{
context->data = pConfig->mapData.hBufferHdr;
if (context->data == NULL)
{
// null pointer, allocate memory
context->data = malloc(context->size);
if (context->data == NULL)
{
dbgPrint("SEGAAPI_CreateBuffer() SEGA_ERROR_OUT_OF_MEMORY");
return SEGA_ERROR_OUT_OF_MEMORY;
}
dbgPrint("SEGAAPI_CreateBuffer() bad pointer, allocated %i data bytes", context->size);
}
else
dbgPrint("SEGAAPI_CreateBuffer() reusing memory 0x%x", context->data);
}
// We should allocate new buffer which the caller will fill
else
{
context->data = malloc(context->size);
if (context->data == NULL)
{
dbgPrint("SEGAAPI_CreateBuffer() SEGA_ERROR_OUT_OF_MEMORY");
return SEGA_ERROR_OUT_OF_MEMORY;
}
dbgPrint("SEGAAPI_CreateBuffer() allocated %i data bytes", context->size);
}
pConfig->mapData.hBufferHdr = context->data;
alGenBuffers(1, &context->alBuffer);
alGenSources(1, &context->alSource);
/*
TODO:
* HABUF_ALLOC_USER_MEM bit when set indicates caller allocate sound data memory buffer.
* HABUF_USE_MAPPED_MEM
Can't be used at the same time!!!
*/
if (context->synthesizer)
{
dbgPrint("SEGAAPI_CreateBuffer() !!! Doesn't support synth buffers yet!");
// https://stackoverflow.com/questions/44157238/can-i-produce-a-synthetic-sound-using-openal
}
resetBuffer(context);
*phHandle = context;
return SEGA_SUCCESS;
}
int SEGAAPI_DestroyBuffer(void *buffer)
{
dbgPrint("SEGAAPI_DestroyBuffer() 0x%x", buffer);
if (buffer == NULL)
return SEGA_ERROR_BAD_PARAM;
free(buffer);
return SEGA_SUCCESS;
}
int SEGAAPI_SetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize)
{
dbgPrint("SEGAAPI_SetGlobalEAXProperty() 0x%x 0x%x 0x%x 0x%x", guid, ulProperty, pData, ulDataSize);
return SEGA_SUCCESS;
}
int SEGAAPI_GetGlobalEAXProperty(GUID *guid, unsigned long ulProperty, void *pData, unsigned long ulDataSize)
{
dbgPrint("SEGAAPI_GetGlobalEAXProperty() 0x%x 0x%x 0x%x 0x%x", guid, ulProperty, pData, ulDataSize);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetSPDIFOutChannelStatus(unsigned int dwChannelStatus, unsigned int dwExtChannelStatus)
{
dbgPrint("SEGAAPI_SetSPDIFOutChannelStatus() 0x%x 0x%x", dwChannelStatus, dwExtChannelStatus);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_GetSPDIFOutChannelStatus(unsigned int *pdwChannelStatus, unsigned int *pdwExtChannelStatus)
{
dbgPrint("SEGAAPI_GetSPDIFOutChannelStatus() 0x%x 0x%x", pdwChannelStatus, pdwExtChannelStatus);
return SEGA_ERROR_UNSUPPORTED;
}
int SEGAAPI_SetSPDIFOutSampleRate(SPDIFOutputSampleRate dwSamplingRate)
{
dbgPrint("SEGAAPI_SetSPDIFOutSampleRate() 0x%x", dwSamplingRate);
return SEGA_ERROR_UNSUPPORTED;
}
SPDIFOutputSampleRate SEGAAPI_GetSPDIFOutSampleRate(void)
{
dbgPrint("SEGAAPI_GetSPDIFOutSampleRate()");
return SPDIFOUT_48KHZ;
}
int SEGAAPI_SetSPDIFOutChannelRouting(unsigned int dwChannel, Routing dwSource)
{
switch (dwChannel)
{
case OUT_FRONT_LEFT:
dbgPrint("SEGAAPI_SetSPDIFOutChannelRouting() dwChannel = LEFT; dwSource = 0x%x", dwSource);
break;
case OUT_FRONT_RIGHT:
dbgPrint("SEGAAPI_SetSPDIFOutChannelRouting() dwChannel = RIGHT; dwSource = 0x%x", dwSource);
break;
default:
dbgPrint("SEGAAPI_SetSPDIFOutChannelRouting() dwChannel = UNKNOWN; dwSource = 0x%x", dwSource);
break;
}
return SEGA_ERROR_UNSUPPORTED;
}
Routing SEGAAPI_GetSPDIFOutChannelRouting(unsigned int dwChannel)
{
dbgPrint("SEGAAPI_GetSPDIFOutChannelRouting() 0x%x", dwChannel);
return UNUSED_PORT;
}
int SEGAAPI_SetIOVolume(SoundBoardIO dwPhysIO, unsigned int dwVolume)
{
// float v = (dwVolume >> 16) & 0xffff;
dbgPrint("SEGAAPI_SetIOVolume() 0x%x 0x%x", dwPhysIO, dwVolume);
// alListenerf(AL_GAIN, v);
return SEGA_SUCCESS;
}
unsigned int SEGAAPI_GetIOVolume(SoundBoardIO dwPhysIO)
{
dbgPrint("SEGAAPI_GetIOVolume() 0x%x", dwPhysIO);
return 0xffffffff;
}
void SEGAAPI_SetLastStatus(int LastStatus)
{
dbgPrint("SEGAAPI_SetLastStatus() 0x%x", LastStatus);
return;
}
int SEGAAPI_GetLastStatus(void)
{
dbgPrint("SEGAAPI_GetLastStatus()");
return SEGA_SUCCESS;
}
int SEGAAPI_Reset(void)
{
dbgPrint("SEGAAPI_Reset()");
return SEGA_SUCCESS;
}
int SEGAAPI_Init(void)
{
dbgPrint("SEGAAPI_Init()");
if (alutInit(NULL, NULL) == AL_FALSE)
{
dbgPrint("SEGAAPI_Init() alutInit() failed!");
return SEGA_ERROR_FAIL;
}
return SEGA_SUCCESS;
}
int SEGAAPI_Exit(void)
{
dbgPrint("SEGAAPI_Exit()");
alutExit();
return SEGA_SUCCESS;
}

File diff suppressed because it is too large Load Diff

2
src/libxdiff/AUTHORS Normal file
View File

@ -0,0 +1,2 @@
Davide Libenzi <davidel@xmailserver.org>

504
src/libxdiff/COPYING Normal file
View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

5
src/libxdiff/ChangeLog Normal file
View File

@ -0,0 +1,5 @@
* Sun, Mar 26 2006 - Davide Libenzi <davidel@xmailserver.org>
Fixed the missing end of line problem for text diff and patch.

236
src/libxdiff/INSTALL Normal file
View File

@ -0,0 +1,236 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script). Here is a another example:
/bin/bash ./configure CONFIG_SHELL=/bin/bash
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
configuration-related scripts to be executed by `/bin/bash'.
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

3
src/libxdiff/Makefile.am Normal file
View File

@ -0,0 +1,3 @@
SUBDIRS = . xdiff test tools man

616
src/libxdiff/Makefile.in Normal file
View File

@ -0,0 +1,616 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
compile config.guess config.sub depcomp install-sh ltmain.sh \
missing mkinstalldirs
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = . xdiff test tools man
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
cd $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr \
distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
check-am clean clean-generic clean-libtool clean-recursive \
ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
dist-shar dist-tarZ dist-zip distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-recursive distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
tags tags-recursive uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

0
src/libxdiff/NEWS Normal file
View File

0
src/libxdiff/README Normal file
View File

7514
src/libxdiff/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

99
src/libxdiff/compile Executable file
View File

@ -0,0 +1,99 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
# Copyright 1999, 2000 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Usage:
# compile PROGRAM [ARGS]...
# `-o FOO.o' is removed from the args passed to the actual compile.
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status

1466
src/libxdiff/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

102
src/libxdiff/config.h.in Normal file
View File

@ -0,0 +1,102 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `free' function. */
#undef HAVE_FREE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the `malloc' function. */
#undef HAVE_MALLOC
/* Define to 1 if you have the `memchr' function. */
#undef HAVE_MEMCHR
/* Define to 1 if you have the `memcmp' function. */
#undef HAVE_MEMCMP
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the `realloc' function. */
#undef HAVE_REALLOC
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlen' function. */
#undef HAVE_STRLEN
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
#undef volatile

1579
src/libxdiff/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

22226
src/libxdiff/configure vendored Executable file

File diff suppressed because it is too large Load Diff

32
src/libxdiff/configure.in Normal file
View File

@ -0,0 +1,32 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(libxdiff, 0.23)
AM_INIT_AUTOMAKE(libxdiff, 0.23)
AM_CONFIG_HEADER(config.h)
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LIBTOOL
CFLAGS="${CFLAGS=}"
dnl Checks for libraries.
dnl Checks for header files.
AC_STDC_HEADERS
AC_CHECK_HEADERS(stdio.h limits.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_C_VOLATILE
AC_C_CONST
AC_C_BIGENDIAN
dnl Checks for library functions.
AC_CHECK_FUNCS(memset memcmp memchr memcpy strlen malloc free realloc)
AC_OUTPUT(Makefile xdiff/Makefile test/Makefile tools/Makefile man/Makefile)

530
src/libxdiff/depcomp Executable file
View File

@ -0,0 +1,530 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2005-07-09.11
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mecanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

323
src/libxdiff/install-sh Executable file
View File

@ -0,0 +1,323 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-05-14.22
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

6426
src/libxdiff/ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

175
src/libxdiff/makefile.win32 Normal file
View File

@ -0,0 +1,175 @@
!IF "$(CFG)" == ""
CFG=debug
!ENDIF
!IF "$(CFG)" != "release" && "$(CFG)" != "debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE nmake /f makefile CFG=debug
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "release" ( Win32 x86 release build )
!MESSAGE "debug" ( Win32 x86 debug build)
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
XDIFFLIB=xdiff.lib
XREGRESSION=xregression.exe
XDIFFTEST=xdifftest.exe
XDIFF_SRCDIR=.\xdiff
TEST_SRCDIR=.\test
INCL_DIRS=/I"$(XDIFF_SRCDIR)" /I"$(TEST_SRCDIR)" /I"."
CFLAGS=/D "WIN32" /D "HAVE_WINCONFIG_H" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" $(INCL_DIRS)
!IF "$(CFG)" == "release"
OUTDIR=.\release
CPP_FLAGS=/nologo $(CFLAGS) /Zp1 /MT /W3 /O2 /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(OUTDIR)\\" /FD /c
!ELSEIF "$(CFG)" == "debug"
OUTDIR=.\debug
CPP_FLAGS=/nologo $(CFLAGS) /Zp1 /MTd /Zi /W3 /Gm /Od /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(OUTDIR)\\" /FD /c
!ENDIF
CPP=cl.exe
LIB32=lib.exe
LIB32_FLAGS=/nologo /machine:I386
LINK32=link.exe
LINK32_FLAGS="$(OUTDIR)\$(XDIFFLIB)" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /machine:I386
XDIFFLIB_OBJS= \
"$(OUTDIR)\xadler32.obj" \
"$(OUTDIR)\xbdiff.obj" \
"$(OUTDIR)\xbpatchi.obj" \
"$(OUTDIR)\xmerge3.obj" \
"$(OUTDIR)\xdiffi.obj" \
"$(OUTDIR)\xemit.obj" \
"$(OUTDIR)\xmissing.obj" \
"$(OUTDIR)\xpatchi.obj" \
"$(OUTDIR)\xprepare.obj" \
"$(OUTDIR)\xversion.obj" \
"$(OUTDIR)\xalloc.obj" \
"$(OUTDIR)\xutils.obj" \
"$(OUTDIR)\xrabdiff.obj"
XREGRESSION_OBJS= \
"$(OUTDIR)\xregression.obj" \
"$(OUTDIR)\xtestutils.obj"
XDIFFTEST_OBJS= \
"$(OUTDIR)\xdiff_test.obj" \
"$(OUTDIR)\xtestutils.obj"
ALL : "$(OUTDIR)\$(XDIFFLIB)" "$(OUTDIR)\$(XREGRESSION)" "$(OUTDIR)\$(XDIFFTEST)"
CLEAN :
-@erase "$(OUTDIR)\$(XDIFFLIB)" "$(OUTDIR)\$(XREGRESSION)" "$(OUTDIR)\$(XDIFFTEST)"
-@erase $(XDIFFLIB_OBJS) $(XREGRESSION_OBJS) $(XDIFFTEST_OBJS)
-@erase *.pdb *.idb *.pch
"$(OUTDIR)" :
if not exist "$(OUTDIR)\$(NULL)" mkdir "$(OUTDIR)"
"$(OUTDIR)\$(XDIFFLIB)" : "$(OUTDIR)" $(XDIFFLIB_OBJS)
$(LIB32) @<<
$(LIB32_FLAGS) /out:"$(OUTDIR)\$(XDIFFLIB)" $(XDIFFLIB_OBJS)
<<
"$(OUTDIR)\$(XREGRESSION)" : "$(OUTDIR)" $(XREGRESSION_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) /out:"$(OUTDIR)\$(XREGRESSION)" $(XREGRESSION_OBJS)
<<
"$(OUTDIR)\$(XDIFFTEST)" : "$(OUTDIR)" $(XDIFFTEST_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) /out:"$(OUTDIR)\$(XDIFFTEST)" $(XDIFFTEST_OBJS)
<<
SOURCE="$(XDIFF_SRCDIR)\xalloc.c"
"$(OUTDIR)\xalloc.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xadler32.c"
"$(OUTDIR)\xadler32.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xmissing.c"
"$(OUTDIR)\xmissing.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xbdiff.c"
"$(OUTDIR)\xbdiff.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xbpatchi.c"
"$(OUTDIR)\xbpatchi.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xmerge3.c"
"$(OUTDIR)\xmerge3.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xdiffi.c"
"$(OUTDIR)\xdiffi.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xemit.c"
"$(OUTDIR)\xemit.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xpatchi.c"
"$(OUTDIR)\xpatchi.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xprepare.c"
"$(OUTDIR)\xprepare.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xutils.c"
"$(OUTDIR)\xutils.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xrabdiff.c"
"$(OUTDIR)\xrabdiff.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(XDIFF_SRCDIR)\xversion.c"
"$(OUTDIR)\xversion.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(TEST_SRCDIR)\xregression.c"
"$(OUTDIR)\xregression.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(TEST_SRCDIR)\xtestutils.c"
"$(OUTDIR)\xtestutils.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)
SOURCE="$(TEST_SRCDIR)\xdiff_test.c"
"$(OUTDIR)\xdiff_test.obj" : $(SOURCE) "$(OUTDIR)"
$(CPP) $(CPP_FLAGS) $(SOURCE)

View File

@ -0,0 +1,5 @@
man3_MANS = xdiff.3
EXTRA_DIST = $(man3_MANS)

View File

@ -0,0 +1,373 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff
MANS = $(man3_MANS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
man3_MANS = xdiff.3
EXTRA_DIST = $(man3_MANS)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu man/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-man3: $(man3_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(mkdir_p) "$(DESTDIR)$(man3dir)"
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
done
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
for dir in "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-man
install-exec-am:
install-info: install-info-am
install-man: install-man3
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-man
uninstall-man: uninstall-man3
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-man3 \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-info-am uninstall-man \
uninstall-man3
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

6
src/libxdiff/man/mkpages.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
groff -t -e -mandoc -Tascii xdiff.3 | col -bx > xdiff.txt
groff -t -e -mandoc -Tps xdiff.3 | ps2pdf - xdiff.pdf
man2html < xdiff.3 | sed 's/<BODY>/<BODY text="#0000FF" bgcolor="#FFFFFF" style="font-family: monospace;">/i' > xdiff.html

View File

@ -0,0 +1,105 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="Author" content="Davide Libenzi">
<meta name="GENERATOR" content="Mozilla 1.2">
<meta name="Keywords"
content="diff,patch,library,portable,file,difference,binary diff,binary patch,myers,macdonald">
<title>LibXDiff Home Page</title>
</head>
<body style="color: rgb(0, 0, 255);">
<p style="font-family: monospace;" align="center"><b>LibXDiff</b><br>
</p>
<p style="font-family: monospace;" align="left">&nbsp;<br>
The <b>LibXDiff</b> library implements basic and yet complete
functionalities to create file differences/patches to both binary and
text files. The library uses memory files as file abstraction to
achieve
both performance and portability. For binary files, <b>LibXDiff</b>
implements both (with some modification) the algorithm described in <i>File
System Support for Delta Compression</i> by <i>Joshua P. MacDonald</i>,
and the algorithm described in <span style="font-style: italic;">Fingerprinting
By Random Polynomials</span> by <span style="font-style: italic;">Michael
O. Rabin</span>. While for text files it follows directives described
in <i>An O(ND)
Difference Algorithm and Its Variations</i> by <i>Eugene W. Myers</i>.
Memory files used by the library are basically a collection of buffers
that store the file content. There are two different requirements for
memory files when passed to diff/patch functions. Text files for
diff/patch functions require that a single line do not have to spawn
across two different memory file blocks. Binary diff/patch functions
require memory files to be compact. A compact memory files is a file
whose content is stored inside a single block. Functionalities inside
the library are available to satisfy these rules. Using the <b>XDL_MMF_ATOMIC</b>
memory file flag it is possible to make writes to not split the written
record across different blocks, while the functions <b>xdl_mmfile_iscompact</b>()
, <b>xdl_mmfile_compact</b>() and <b>xdl_mmfile_writeallocate</b>()
are usefull to test if the file is compact and to create a compacted
version of the file itself. The text file differential output uses the
raw unified output format, by omitting the file header since the result
is always relative to a single compare operation (between two files).
The output format of the binary patch file is proprietary (and binary)
and it is basically a collection of copy and insert commands, like
described inside the MacDonald paper. The library is compatible with
almost every Unix implementation (configure script) and it is also
compatible with Windows through custom (nmake) make files. Examples are
available inside the <span style="font-style: italic;">test</span>
subdirectory of the distribution tarball that show how to use the
library. Also, inside the same subdirectory, a regression test in
available that tests the library with random data by requiring a diff
followed by a patch and comparing results. Regression tests ran
successfully for days on my Linux, Solaris, FreeBSD and Windows boxes,
and this makes me believe that the library itself is completely ready
for production (despite the version number).<br>
</p>
<p style="font-family: monospace;" align="left"><br>
</p>
<p style="text-align: center; font-family: monospace;"><b>Documentation<br>
</b></p>
<div style="text-align: left; font-family: monospace;"><br>
The <span style="font-weight: bold;">LibXDiff</span> library man page
is available : <a href="xdiff.html">HTML</a>&nbsp;&nbsp;&nbsp;<a
href="xdiff.txt">TXT</a>&nbsp;&nbsp;&nbsp; <a href="xdiff.pdf">PDF<br>
</a><br>
<br>
</div>
<p style="font-family: monospace;" align="center"><b>License
and Software</b></p>
<p style="font-family: monospace;" align="left"><span
style="font-weight: bold;">LibXDiff</span>&nbsp;
is made available through the <a
href="http://www.gnu.org/copyleft/lesser.html">GNU LGPL</a> license
together with the complete sources. Please read carefully the <a
href="http://www.gnu.org/copyleft/lesser.html">license</a> before
using
the software. The latest library package is available here :</p>
<p style="font-family: monospace;" align="left"><a
href="http://www.xmailserver.org/libxdiff-0.23.tar.gz">Version
0.23</a></p>
<p style="font-family: monospace;" align="left"><br>
</p>
<p style="text-align: center; font-family: monospace;"><b>Links And Docs<br>
</b></p>
<div style="text-align: left; font-family: monospace;"><a
href="http://freshmeat.net/projects/xdiff-lib">LibXDiff FreshMeat Home
Page</a><a href="http://www.gnu.org/software/diffutils/diffutils.html"><br>
GNU DiffUtil</a><br>
<a href="diff2.pdf"><span style="font-style: italic;">An O(ND)
Difference Algorithm and Its Variations</span> by <i>Eugene W. Myers</i></a><br>
<a href="xdfs.pdf"><i>File System Support for Delta Compression</i> by <i>Joshua
P. MacDonald</i></a><br>
<a href="rabin.pdf"><i>Fingerprinting By Random Polynomials</i> by <i>Michael
O. Rabin</i></a><br>
<a href="rabin_impl.pdf"><i>Fingerprinting Using Polynomial</i> by <i>Calvin
Chan</i> and <i>Hahua Lu</i></a><br>
<a href="rabin_apps.pdf"><i>Some Applications of Rabin's Fingerprinting
Method</i> by <i>Andrei Z. Broder</i></a><br>
<br>
<br>
<br>
<a href="davide.html">Back Home</a><br>
<br>
<br>
</div>
</body>
</html>

871
src/libxdiff/man/xdiff.3 Normal file
View File

@ -0,0 +1,871 @@
.\"
.\" LibXDiff by Davide Libenzi ( File Differential Library )
.\" Copyright (C) 2003 Davide Libenzi
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program; if not, write to the Free Software
.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
.\"
.\" Davide Libenzi <davidel@xmailserver.org>
.\"
.na
.TH LibXDiff 3 "0.23" "GNU" "File Differential Library"
.SH NAME
xdl_set_allocator, xdl_malloc, xdl_free, xdl_realloc, xdl_init_mmfile, xdl_free_mmfile,
xdl_mmfile_iscompact, xdl_seek_mmfile, xdl_read_mmfile, xdl_write_mmfile, xdl_writem_mmfile,
xdl_mmfile_writeallocate, xdl_mmfile_ptradd, xdl_mmfile_first, xdl_mmfile_next, xdl_mmfile_size, xdl_mmfile_cmp,
xdl_mmfile_compact, xdl_diff, xdl_patch, xdl_merge3, xdl_bdiff_mb, xdl_bdiff, xdl_rabdiff_mb, xdl_rabdiff,
xdl_bdiff_tgsize, xdl_bpatch \- File Differential Library support functions
.SH SYNOPSIS
.nf
.B #include <xdiff.h>
.sp
.BI "int xdl_set_allocator(memallocator_t const *" malt ");"
.nl
.BI "void *xdl_malloc(unsigned int " size ");"
.nl
.BI "void xdl_free(void *" ptr ");"
.nl
.BI "void *xdl_realloc(void *" ptr ", unsigned int " nsize ");"
.nl
.BI "int xdl_init_mmfile(mmfile_t *" mmf ", long " bsize ", unsigned long " flags ");"
.nl
.BI "void xdl_free_mmfile(mmfile_t *" mmf ");"
.nl
.BI "int xdl_mmfile_iscompact(mmfile_t *" mmf ");"
.nl
.BI "int xdl_seek_mmfile(mmfile_t *" mmf ", long " off ");"
.nl
.BI "long xdl_read_mmfile(mmfile_t *" mmf ", void *" data ", long " size ");"
.nl
.BI "long xdl_write_mmfile(mmfile_t *" mmf ", void const *" data ", long " size ");"
.nl
.BI "long xdl_writem_mmfile(mmfile_t *" mmf ", mmbuffer_t *" mb ", int " nbuf ");"
.nl
.BI "void *xdl_mmfile_writeallocate(mmfile_t *" mmf ", long " size ");"
.nl
.BI "long xdl_mmfile_ptradd(mmfile_t *" mmf ", char *" ptr ", long " size ", unsigned long " flags ");"
.nl
.BI "void *xdl_mmfile_first(mmfile_t *" mmf ", long *" size ");"
.nl
.BI "void *xdl_mmfile_next(mmfile_t *" mmf ", long *" size ");"
.nl
.BI "long xdl_mmfile_size(mmfile_t *" mmf ");"
.nl
.BI "int xdl_mmfile_cmp(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ");"
.nl
.BI "int xdl_mmfile_compact(mmfile_t *" mmfo ", mmfile_t *" mmfc ", long " bsize ", unsigned long " flags ");"
.nl
.BI "int xdl_diff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xpparam_t const *" xpp ", xdemitconf_t const *" xecfg ", xdemitcb_t *" ecb ");"
.nl
.BI "int xdl_patch(mmfile_t *" mmf ", mmfile_t *" mmfp ", int " mode ", xdemitcb_t *" ecb ", xdemitcb_t *" rjecb ");"
.nl
.BI "int xdl_merge3(mmfile_t *" mmfo ", mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xdemitcb_t *" ecb ", xdemitcb_t *" rjecb ");"
.nl
.BI "int xdl_bdiff_mb(mmbuffer_t *" mmb1 ", mmbuffer_t *" mmb2 ", bdiffparam_t const *" bdp ", xdemitcb_t *" ecb ");"
.nl
.BI "int xdl_bdiff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", bdiffparam_t const *" bdp ", xdemitcb_t *" ecb ");"
.nl
.BI "int xdl_rabdiff_mb(mmbuffer_t *" mmb1 ", mmbuffer_t *" mmb2 ", xdemitcb_t *" ecb ");"
.nl
.BI "int xdl_rabdiff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xdemitcb_t *" ecb ");"
.nl
.BI "long xdl_bdiff_tgsize(mmfile_t *" mmfp ");"
.nl
.BI "int xdl_bpatch(mmfile_t *" mmf ", mmfile_t *" mmfp ", xdemitcb_t *" ecb ");"
.SH DESCRIPTION
The
.B LibXDiff
library implements basic and yet complete functionalities to create
file differences/patches to both binary and text files. The library
uses memory files as file abstraction to achieve both performance and
portability. For binary files,
.B LibXDiff
implements both (with some modification) the algorithm described in
.IR "File System Support for Delta Compression" " by " "Joshua P. MacDonald" ,
and the method described in
.IR "Fingerprinting by Random Polynomials" " by " "Michael O. Rabin" "."
While for text files it follows directives described in
.IR "An O(ND) Difference Algorithm and Its Variations" " by " "Eugene W. Myers" .
Memory files used by the library are basically a collection of buffers
that store the file content. There are two different requirements for memory
files when passed to diff/patch functions. Text files for diff/patch functions
require that a single line do not have to spawn across two different memory
file blocks. Binary diff/patch functions require memory files to be compact.
A compact memory files is a file whose content is stored inside a single block.
Functionalities inside the library are available to satisfy these rules.
Using the
.B XDL_MMF_ATOMIC
memory file flag it is possible to make writes to not split the written
record across different blocks, while the functions
.BR xdl_mmfile_iscompact ()
,
.BR xdl_mmfile_compact ()
and
.BR xdl_mmfile_writeallocate ()
are usefull to test if the file is compact and to create a compacted version
of the file itself. The text file differential output uses the raw unified output
format, by omitting the file header since the result is always relative to
a single compare operation (between two files). The output format of the binary
patch file is proprietary (and binary) and it is basically a collection of
copy and insert commands, like described inside the MacDonald paper.
.SS Functions
The following functions are defined:
.TP
.BI "int xdl_set_allocator(memallocator_t const *" malt ");"
The
.B LibXDiff
library enable the user to set its own memory allocator, that will be used
for all the following memory requests. The allocator must be set before
to start calling the
.B LibXDiff
library with a call to
.BR xdl_set_allocator ().
The memory allocator structure contains the following members:
.nf
typedef struct s_memallocator {
void *priv;
void *(*malloc)(void *priv, unsigned int size);
void (*free)(void *priv, void *ptr);
void *(*realloc)(void *priv, void *ptr, unsigned int nsize);
} memallocator_t;
.fi
The
.BR malloc ()
function pointer will be used by
.B LibXDiff
to request a memory block of
.I size
bytes. The
.BR free ()
function pointer will be called to free a previously allocated block
.I ptr
, while the
.BR realloc ()
will be used to resize the
.I ptr
to a new
.I nsize
size in bytes. The
.B priv
structure member will be passed to the
.BR malloc (), free (), realloc ()
functions as first parameter. The
.B LibXDiff
user must call
.BR xdl_set_allocator ()
before starting using the library, otherwise
.B LibXDiff
functions will fail due to the lack of memory allocation support.
A typical initialization sequence for
.B POSIX
systems will use the standard
.BR malloc (3),
.BR free (3),
.BR realloc (3)
and will look like:
.nf
void *wrap_malloc(void *priv, unsigned int size) {
return malloc(size);
}
void wrap_free(void *priv, void *ptr) {
free(ptr);
}
void *wrap_realloc(void *priv, void *ptr, unsigned int size) {
return realloc(ptr, size);
}
void my_init_xdiff(void) {
memallocator_t malt;
malt.priv = NULL;
malt.malloc = wrap_malloc;
malt.free = wrap_free;
malt.realloc = wrap_realloc;
xdl_set_allocator(&malt);
}
.fi
.TP
.BI "void *xdl_malloc(unsigned int " size ");"
Allocates a memory block of
.I size
bytes using the
.B LibXDiff
memory allocator. The user can specify its own allocator using the
.BR xdl_set_allocator ()
function. The
.BR xdl_malloc ()
return a pointer to the newly allocated block, or
.B NULL
in case of failure.
.TP
.BI "void xdl_free(void *" ptr ");"
Free a previously allocated memory block pointed by
.IR ptr .
The
.I ptr
block must has been allocated using either
.BR xdl_malloc ()
or
.BR xdl_realloc ().
.TP
.BI "void *xdl_realloc(void *" ptr ", unsigned int " nsize ");"
Resizes the memory block pointed by
.I ptr
to a new size
.IR nsize .
Return the resized block if successful, or
.B NULL
in case the reallocation fails. After a successful reallocation, the old
.I ptr
block is to be considered no more valid.
.TP
.BI "int xdl_init_mmfile(mmfile_t *" mmf ", long " bsize ", unsigned long " flags ");"
Initialize the memory file
.I mmf
by requiring an internal block size of
.IR bsize .
The
.I flags
parameter is a combination of the following flags :
.br
.IP
.B XDL_MMF_ATOMIC
Writes on the memory file will be atomic. That is, the data will not be split
on two or more different blocks.
Once an
.BR xdl_init_mmfile ()
succeeded, a matching
.BR xdl_free_mmfile ()
must be called when the user has done using the memory file, otherwise serious
memory leaks will happen.
The function return 0 if succeed or -1 if an error is encountered.
.TP
.BI "void xdl_free_mmfile(mmfile_t *" mmf ");"
Free all the data associated with the
.I mmf
memory file.
.TP
.BI "int xdl_mmfile_iscompact(mmfile_t *" mmf ");"
Returns an integer different from 0 if the
.I mmf
memory file is compact, 0 otherwise. A compact memory file is one that have
the whole content stored inside a single block.
.TP
.BI "int xdl_seek_mmfile(mmfile_t *" mmf ", long " off ");"
Set the current data pointer of the memory file
.I mmf
to the specified offset
.I off
from the beginning of the file itself. Returns 0 if successful or -1 if an error
happened.
.TP
.BI "long xdl_read_mmfile(mmfile_t *" mmf ", void *" data ", long " size ");"
Request to read
.I size
bytes from the memory file
.I mmf
by storing the data inside the
.I data
buffer. Returns the number of bytes read into the
.I data
buffer. The amount of data read can be lower than the specified
.IR size .
The function returns -1 if an error happened.
.TP
.BI "long xdl_write_mmfile(mmfile_t *" mmf ", void const *" data ", long " size ");"
Request to write
.I size
bytes from the specified buffer
.I data
into the memory file
.IR mmf .
If the memory file has been created using the
.B XDL_MMF_ATOMIC
flag, the write request will not be split across different blocks.
Note that all write operations done on memory files do append data at the end
the file, and writes in the middle of it are allowed. This is because the library
memory file abstraction does not need this functionality to be available.
The function returns the number of bytes written or a number lower than
.I size
if an error happened.
.TP
.BI "long xdl_writem_mmfile(mmfile_t *" mmf ", mmbuffer_t *" mb ", int " nbuf ");"
Request to sequentially write
.I nbuf
memory buffers passed inside the array
.I mb
into the memory file
.IR mmf .
The memory buffer structure is defined as :
.nf
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
.fi
The
.I ptr
field is a pointer to the user data, whose size is specified inside the
.I size
structure field. The function returns the total number of bytes written
or a lower number if an error happened.
.TP
.BI "void *xdl_mmfile_writeallocate(mmfile_t *" mmf ", long " size ");"
The function request to allocate a write buffer of
.I size
bytes in the
.I mmf
memory file and returns the pointer to the allocated buffer. The user will
have the responsibility to store
.I size
bytes (no more, no less) inside the memory region pointed to by the returned pointer.
The files size will grow of
.I size
bytes as a consequence of this operation. The function will return
.B NULL
if an error happened.
.TP
.BI "long xdl_mmfile_ptradd(mmfile_t *" mmf ", char *" ptr ", long " size ", unsigned long " flags ");"
The function adds a user specified block to the end of the memory file
.IR mmf .
The block first byte is pointed to by
.I ptr
and its length is
.I size
bytes. The
.I flags
parameter can be used to specify attributes of the user memory block. Currently
supported attributes are:
.br
.IP
.B XDL_MMB_READONLY
Specify that the added memory block must be treated as read-only, and
every attempt to write on it should result in a failure of the memory file
writing functions.
The purpose of this function is basically to avoid copying memory around,
by helping the library to not drain the CPU cache. The function returns
.I size
in case of success, or -1 in case of error.
.TP
.BI "void *xdl_mmfile_first(mmfile_t *" mmf ", long *" size ");"
The function is used to return the first block of the
.I mmf
memory file block chain. The
.I size
parameter will receive the size of the block, while the function will return
the pointer the the first byte of the block itself. The function returns
.B NULL
if the file is empty.
.TP
.BI "void *xdl_mmfile_next(mmfile_t *" mmf ", long *" size ");"
The function is used to return the next block of the
.I mmf
memory file block chain. The
.I size
parameter will receive the size of the block, while the function will return
the pointer the the first byte of the block itself. The function returns
.B NULL
if the current block is the last one of the chain.
.TP
.BI "long xdl_mmfile_size(mmfile_t *" mmf ");"
The function returns the size of the specified memory file
.IR mmf .
.TP
.BI "int xdl_mmfile_cmp(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ");"
Request to compare two memory files
.IR mmf1 " and " mmf2
and returns 0 if files are identical, or a value different from 0 if
files are different.
.TP
.BI "int xdl_mmfile_compact(mmfile_t *" mmfo ", mmfile_t *" mmfc ", long " bsize ", unsigned long " flags ");"
Request to create a compact version of the memory file
.I mmfo
into the (uninitialized) memory file
.IR mmfc .
The
.I bsize
parameter specify the requested block size and
.I flags
specify flags to be used to create the new
.I mmfc
memory file (see
.BR xdl_init_mmfile ()
). The function returns 0 if succedded or -1 if an error happened.
.TP
.BI "int xdl_diff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xpparam_t const *" xpp ", xdemitconf_t const *" xecfg ", xdemitcb_t *" ecb ");"
Request to create the difference between the two text memory files
.IR mmf1 " and " mmf2 .
The
.I mmf1
memory files is considered the "old" file while
.I mmf2
is considered the "new" file. So the function will create a patch file
that once applied to
.I mmf1
will give
.I mmf2
as result. Files
.IR mmf1 " and " mmf2
must be atomic from a line point of view (or, as an extreme, compact), that
means that a single test line cannot spread among different memory file blocks.
The
.I xpp
parameter is a pointer to a structure :
.nf
typedef struct s_xpparam {
unsigned long flags;
} xpparam_t;
.fi
that is used to specify parameters to be used by the file differential algorithm.
The
.I flags
field is a combination of the following flags :
.IP
.B XDF_NEED_MINIMAL
Requires the minimal edit script to be found by the algorithm (may be slow).
The
.I xecfg
parameter point to a structure :
.nf
typedef struct s_xdemitconf {
long ctxlen;
} xdemitconf_t;
.fi
that is used to configure the algorithm responsible of the creation the the
differential file from an edit script. The
.I ctxlen
field is used to specify the amount of context to be emitted inside the
differential file (the value 3 is suggested for normal operations).
The parameter
.I ecb
is a pointer to a structure :
.nf
typedef struct s_xdemitcb {
void *priv;
int (*outf)(void *, mmbuffer_t *, int);
} xdemitcb_t;
.fi
that is used by the differential file creation algorithm to emit the created
data. The
.I priv
field is an opaque pointer to a user specified data, while the
.I outf
field point to a callback function that is called internally to emit algorithm
generated data rappresenting the differential file. The first parameter of the
callback is the same
.I priv
field specified inside the
.B xdemitcb_t
structure. The second parameter point to an array of
.B mmbuffer_t
(see above for a definition of the structure) whose element count is specified
inside the last parameter of the callback itself. The callback will always be
called with entire records (lines) and never a record (line) will be emitted
using two different callback calls. This is important because if the called will
use another memory file to store the result, by creating the target memory file with
.B XDL_MMF_ATOMIC
will guarantee the "atomicity" of the memory file itself.
The function returns 0 if succeeded or -1 if an error occurred.
.TP
.BI "int xdl_patch(mmfile_t *" mmf ", mmfile_t *" mmfp ", int " mode ", xdemitcb_t *" ecb ", xdemitcb_t *" rjecb ");"
Request to patch the memory file
.I mmf
using the patch file stored in
.IR mmfp .
The
.I mmf
memory file
.B is not
changed during the operation and can be considered as read only.
The
.I mode
parameter can be one of the following values :
.IP
.B XDL_PATCH_NORMAL
Perform standard patching like if the patch memory file
.I mmfp
has been created using
.I mmf
as "old" file.
.IP
.B XDL_PATCH_REVERSE
Apply the reverse patch. That means that the
.I mmf
memory file has to be considered as if it was specified as "new" file during
the differential operation (
.BR xdl_diff ()
). The result of the operation will then be the file content that was used
as "old" file during the differential operation.
The following flags can be specified (by or-ing them) to one of the above:
.IP
.B XDL_PATCH_IGNOREBSPACE
Ignore the whitespace at the beginning and the end of the line.
The
.I ecb
will be used by the patch algorithm to create the result file while the
.I rjecb
will be used to emit all differential chunks that cannot be applied.
Like explained above, callbacks are always called with entire records to guarantee
atomicity of the resulting output.
The function returns 0 if succeeded without performing any fuzzy hunk detection,
a positive value if it secceeded with fuzzy hunk detection or -1 if an error occurred
during the patch operation.
.TP
.BI "int xdl_merge3(mmfile_t *" mmfo ", mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xdemitcb_t *" ecb ", xdemitcb_t *" rjecb ");"
Merges three files together. The
.I mmfo
file is the original one, while
.IR mmf1 " and " mmf2
are two modified versions of
.IR mmfo .
The function works by creating a differential between
.IR mmfo " and " mmf2
and by applying the resulting patch to
.IR mmf1 .
Because of this sequence,
.I mmf1
changes will be privileged against the ones of
.IR mmf2 .
The
.I ecb
will be used by the patch algorithm to create the result file while the
.I rjecb
will be used to emit all differential chunks that cannot be applied.
Like explained above, callbacks are always called with entire records to guarantee
atomicity of the resulting output.
The function returns 0 if succeeded or -1 if an error occurred during the patch operation.
.TP
.BI "int xdl_bdiff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", bdiffparam_t const *" bdp ", xdemitcb_t *" ecb ");"
Request to create the difference between the two text memory files
.IR mmf1 " and " mmf2 .
The
.I mmf1
memory files is considered the "old" file while
.I mmf2
is considered the "new" file. So the function will create a patch file
that once applied to
.I mmf1
will give
.I mmf2
as result. Files
.IR mmf1 " and " mmf2
must be compact to make it easy and faster to perform the difference operation.
Functions are available to check for compactness (
.BR xdl_mmfile_iscompact ()
) and to make compact a non-compact file (
.BR xdl_mmfile_compact ()
). An example of how to create a compact memory file (described inside the test
subdirectory) is :
.nf
int xdlt_load_mmfile(char const *fname, mmfile_t *mf, int binmode) {
char cc;
int fd;
long size, bsize;
char *blk;
if (xdl_init_mmfile(mf, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0)
return -1;
if ((fd = open(fname, O_RDONLY)) == -1) {
perror(fname);
xdl_free_mmfile(mf);
return -1;
}
if ((size = bsize = lseek(fd, 0, SEEK_END)) > 0 && !binmode) {
if (lseek(fd, -1, SEEK_END) != (off_t) -1 &&
read(fd, &cc, 1) && cc != '\\n')
bsize++;
}
lseek(fd, 0, SEEK_SET);
if (!(blk = (char *) xdl_mmfile_writeallocate(mf, bsize))) {
xdl_free_mmfile(mf);
close(fd);
return -1;
}
if (read(fd, blk, (size_t) size) != (size_t) size) {
perror(fname);
xdl_free_mmfile(mf);
close(fd);
return -1;
}
close(fd);
if (bsize > size)
blk[size] = '\\n';
return 0;
}
.fi
The
.I bdp
parameter points to a structure :
.nf
typedef struct s_bdiffparam {
long bsize;
} bdiffparam_t;
.fi
that is used to pass information to the binary file differential algorithm.
The
.I bsize
parameter specify the size of the block that will be used to decompose
.I mmf1
during the block classification phase of the algorithm (see MacDonald paper).
Suggested values go from 16 to 64, with a preferred power of two characteristic.
The
.I ecb
parameter is used to pass the emission callback to the algorithm responsible
of the output file creation.
The function returns 0 if succeede or -1 if an error is occurred.
.TP
.BI "int xdl_bdiff_mb(mmbuffer_t *" mmb1 ", mmbuffer_t *" mmb2 ", bdiffparam_t const *" bdp ", xdemitcb_t *" ecb ");"
Same as
.BR xdl_bdiff ()
but it works on memory buffer directly. The
.BR xdl_bdiff ()
is implemented internally with a
.BR xdl_bdiff_mb ()
after having setup the two memory buffers from the passed memory files (that must be compact,
as described above). The memory buffer structure is defined as :
.nf
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
.fi
An empty memory buffer is specified by setting the
.I ptr
member as
.B NULL
and the
.I size
member as zero. The reason of having this function is to avoid the memory file
preparation, that might involve copying memory from other sources. Using
the
.BR xdl_bdiff_mb (),
the caller can setup the two memory buffer by using, for example,
.BR mmap (2),
and hence avoiding unnecessary memory copies. The other parameters and the return value
of the function
.BR xdl_bdiff_mb ()
are the same as the ones already described in
.BR xdl_bdiff ().
.TP
.BI "int xdl_rabdiff(mmfile_t *" mmf1 ", mmfile_t *" mmf2 ", xdemitcb_t *" ecb ");"
Request to create the difference between the two text memory files
.IR mmf1 " and " mmf2
using the Rabin's polynomial fingerprinting algorithm. This algorithm typically
performs faster and produces smaller deltas, when compared to the XDelta-like one.
The
.I mmf1
memory files is considered the "old" file while
.I mmf2
is considered the "new" file. So the function will create a patch file
that once applied to
.I mmf1
will give
.I mmf2
as result. Files
.IR mmf1 " and " mmf2
must be compact to make it easy and faster to perform the difference operation.
Functions are available to check for compactness (
.BR xdl_mmfile_iscompact ()
) and to make compact a non-compact file (
.BR xdl_mmfile_compact ()
). The
.I ecb
parameter is used to pass the emission callback to the algorithm responsible
of the output file creation.
The function returns 0 if succeede or -1 if an error is occurred.
.TP
.BI "int xdl_rabdiff_mb(mmbuffer_t *" mmb1 ", mmbuffer_t *" mmb2 ", xdemitcb_t *" ecb ");"
Same as
.BR xdl_rabdiff ()
but it works on memory buffer directly. The memory buffer structure is defined as :
.nf
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
.fi
An empty memory buffer is specified by setting the
.I ptr
member as
.B NULL
and the
.I size
member as zero. The reason of having this function is to avoid the memory file
preparation, that might involve copying memory from other sources. Using
the
.BR xdl_rabdiff_mb (),
the caller can setup the two memory buffer by using, for example,
.BR mmap (2),
and hence avoiding unnecessary memory copies. The other parameters and the return value
of the function
.BR xdl_rabdiff_mb ()
are the same as the ones already described in
.BR xdl_rabdiff ().
.TP
.BI "long xdl_bdiff_tgsize(mmfile_t *" mmfp ");"
Given a binary memory file patch, it returns the size that the result file
will have once the patch is applied to the target file. It can be used to
pre-allocate (or write-allocate) a memory block to store the patch result
so that a compact file will be available at the end of the operation. The
function returns the requested size, or -1 if an error occurred during the operation.
.TP
.BI "int xdl_bpatch(mmfile_t *" mmf ", mmfile_t *" mmfp ", xdemitcb_t *" ecb ");"
Request to patch the binary memory file
.I mmf
using the binary patch file stored in
.IR mmfp .
The
.I mmf
memory file
.B is not
changed during the operation and can be considered as read only. The binary
patch algorithm has no notion of context, so the patch operation cannot be
partial (either success or failure). The
.I ecb
parameter contain the callabck (see above for description) used by the binary
patch algorithm to emit the result file. The function returns 0 if succeeded
or -1 if an error occurred during the patch operation.
.SH SEE ALSO
Two papers drove the content of this library and these are :
.br
.IP o
.IR "File System Support for Delta Compression" " by " "Joshua P. MacDonald"
.BR http://www.xmailserver.org/xdfs.pdf
.br
.IP o
.IR "Fingerprinting by Random Polynomials" " by " "Michael O. Rabin"
.BR http://www.xmailserver.org/rabin.pdf
.br
.IP o
.IR "An O(ND) Difference Algorithm and Its Variations" " by " "Eugene W. Myers"
.BR http://www.xmailserver.org/diff2.pdf
.PP
Also usefull information can be looked up inside the
.B diffutil
GNU package :
.BR http://www.gnu.org/software/diffutils/diffutils.html
.SH LICENSE
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
A copy of the license is available at :
.BR http://www.gnu.org/copyleft/lesser.html
.SH AUTHOR
Developed by Davide Libenzi
.RB < davidel@xmailserver.org >
.SH AVAILABILITY
The latest version of
.B LibXDiff
can be found at :
.BR http://www.xmailserver.org/xdiff-lib.html
.SH BUGS
There are no known bugs. Bug reports and comments to Davide Libenzi
.RB < davidel@xmailserver.org >

1109
src/libxdiff/man/xdiff.html Normal file

File diff suppressed because it is too large Load Diff

BIN
src/libxdiff/man/xdiff.pdf Normal file

Binary file not shown.

611
src/libxdiff/man/xdiff.txt Normal file
View File

@ -0,0 +1,611 @@
LibXDiff(3) File Differential Library LibXDiff(3)
NAME
xdl_set_allocator, xdl_malloc, xdl_free, xdl_realloc, xdl_init_mmfile,
xdl_free_mmfile, xdl_mmfile_iscompact, xdl_seek_mmfile,
xdl_read_mmfile, xdl_write_mmfile, xdl_writem_mmfile,
xdl_mmfile_writeallocate, xdl_mmfile_ptradd, xdl_mmfile_first,
xdl_mmfile_next, xdl_mmfile_size, xdl_mmfile_cmp, xdl_mmfile_compact,
xdl_diff, xdl_patch, xdl_merge3, xdl_bdiff_mb, xdl_bdiff, xdl_rabd-
iff_mb, xdl_rabdiff, xdl_bdiff_tgsize, xdl_bpatch - File Differential
Library support functions
SYNOPSIS
#include <xdiff.h>
int xdl_set_allocator(memallocator_t const *malt);
void *xdl_malloc(unsigned int size);
void xdl_free(void *ptr);
void *xdl_realloc(void *ptr, unsigned int nsize);
int xdl_init_mmfile(mmfile_t *mmf, long bsize, unsigned long flags);
void xdl_free_mmfile(mmfile_t *mmf);
int xdl_mmfile_iscompact(mmfile_t *mmf);
int xdl_seek_mmfile(mmfile_t *mmf, long off);
long xdl_read_mmfile(mmfile_t *mmf, void *data, long size);
long xdl_write_mmfile(mmfile_t *mmf, void const *data, long size);
long xdl_writem_mmfile(mmfile_t *mmf, mmbuffer_t *mb, int nbuf);
void *xdl_mmfile_writeallocate(mmfile_t *mmf, long size);
long xdl_mmfile_ptradd(mmfile_t *mmf, char *ptr, long size, unsigned long flags);
void *xdl_mmfile_first(mmfile_t *mmf, long *size);
void *xdl_mmfile_next(mmfile_t *mmf, long *size);
long xdl_mmfile_size(mmfile_t *mmf);
int xdl_mmfile_cmp(mmfile_t *mmf1, mmfile_t *mmf2);
int xdl_mmfile_compact(mmfile_t *mmfo, mmfile_t *mmfc, long bsize, unsigned long flags);
int xdl_diff(mmfile_t *mmf1, mmfile_t *mmf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
int xdl_patch(mmfile_t *mmf, mmfile_t *mmfp, int mode, xdemitcb_t *ecb, xdemitcb_t *rjecb);
int xdl_merge3(mmfile_t *mmfo, mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb, xdemitcb_t *rjecb);
int xdl_bdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, bdiffparam_t const *bdp, xdemitcb_t *ecb);
int xdl_bdiff(mmfile_t *mmf1, mmfile_t *mmf2, bdiffparam_t const *bdp, xdemitcb_t *ecb);
int xdl_rabdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, xdemitcb_t *ecb);
int xdl_rabdiff(mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb);
long xdl_bdiff_tgsize(mmfile_t *mmfp);
int xdl_bpatch(mmfile_t *mmf, mmfile_t *mmfp, xdemitcb_t *ecb);
DESCRIPTION
The LibXDiff library implements basic and yet complete functionalities
to create file differences/patches to both binary and text files. The
library uses memory files as file abstraction to achieve both perfor-
mance and portability. For binary files, LibXDiff implements both (with
some modification) the algorithm described in File System Support for
Delta Compression by Joshua P. MacDonald, and the method described in
Fingerprinting by Random Polynomials by Michael O. Rabin. While for
text files it follows directives described in An O(ND) Difference Algo-
rithm and Its Variations by Eugene W. Myers. Memory files used by the
library are basically a collection of buffers that store the file con-
tent. There are two different requirements for memory files when passed
to diff/patch functions. Text files for diff/patch functions require
that a single line do not have to spawn across two different memory
file blocks. Binary diff/patch functions require memory files to be
compact. A compact memory files is a file whose content is stored
inside a single block. Functionalities inside the library are avail-
able to satisfy these rules. Using the XDL_MMF_ATOMIC memory file flag
it is possible to make writes to not split the written record across
different blocks, while the functions xdl_mmfile_iscompact() ,
xdl_mmfile_compact() and xdl_mmfile_writeallocate() are usefull to test
if the file is compact and to create a compacted version of the file
itself. The text file differential output uses the raw unified output
format, by omitting the file header since the result is always relative
to a single compare operation (between two files). The output format of
the binary patch file is proprietary (and binary) and it is basically a
collection of copy and insert commands, like described inside the Mac-
Donald paper.
Functions
The following functions are defined:
int xdl_set_allocator(memallocator_t const *malt);
The LibXDiff library enable the user to set its own memory allo-
cator, that will be used for all the following memory requests.
The allocator must be set before to start calling the LibXDiff
library with a call to xdl_set_allocator(). The memory alloca-
tor structure contains the following members:
typedef struct s_memallocator {
void *priv;
void *(*malloc)(void *priv, unsigned int size);
void (*free)(void *priv, void *ptr);
void *(*realloc)(void *priv, void *ptr, unsigned int nsize);
} memallocator_t;
The malloc() function pointer will be used by LibXDiff to
request a memory block of size bytes. The free() function
pointer will be called to free a previously allocated block ptr
, while the realloc() will be used to resize the ptr to a new
nsize size in bytes. The priv structure member will be passed to
the malloc(),free(),realloc() functions as first parameter. The
LibXDiff user must call xdl_set_allocator() before starting
using the library, otherwise LibXDiff functions will fail due to
the lack of memory allocation support. A typical initialization
sequence for POSIX systems will use the standard malloc(3),
free(3), realloc(3) and will look like:
void *wrap_malloc(void *priv, unsigned int size) {
return malloc(size);
}
void wrap_free(void *priv, void *ptr) {
free(ptr);
}
void *wrap_realloc(void *priv, void *ptr, unsigned int size) {
return realloc(ptr, size);
}
void my_init_xdiff(void) {
memallocator_t malt;
malt.priv = NULL;
malt.malloc = wrap_malloc;
malt.free = wrap_free;
malt.realloc = wrap_realloc;
xdl_set_allocator(&malt);
}
void *xdl_malloc(unsigned int size);
Allocates a memory block of size bytes using the LibXDiff memory
allocator. The user can specify its own allocator using the
xdl_set_allocator() function. The xdl_malloc() return a pointer
to the newly allocated block, or NULL in case of failure.
void xdl_free(void *ptr);
Free a previously allocated memory block pointed by ptr. The
ptr block must has been allocated using either xdl_malloc() or
xdl_realloc().
void *xdl_realloc(void *ptr, unsigned int nsize);
Resizes the memory block pointed by ptr to a new size nsize.
Return the resized block if successful, or NULL in case the
reallocation fails. After a successful reallocation, the old ptr
block is to be considered no more valid.
int xdl_init_mmfile(mmfile_t *mmf, long bsize, unsigned long flags);
Initialize the memory file mmf by requiring an internal block
size of bsize. The flags parameter is a combination of the fol-
lowing flags :
XDL_MMF_ATOMIC Writes on the memory file will be atomic. That
is, the data will not be split on two or more different blocks.
Once an xdl_init_mmfile() succeeded, a matching
xdl_free_mmfile() must be called when the user has done using
the memory file, otherwise serious memory leaks will happen.
The function return 0 if succeed or -1 if an error is encoun-
tered.
void xdl_free_mmfile(mmfile_t *mmf);
Free all the data associated with the mmf memory file.
int xdl_mmfile_iscompact(mmfile_t *mmf);
Returns an integer different from 0 if the mmf memory file is
compact, 0 otherwise. A compact memory file is one that have the
whole content stored inside a single block.
int xdl_seek_mmfile(mmfile_t *mmf, long off);
Set the current data pointer of the memory file mmf to the spec-
ified offset off from the beginning of the file itself. Returns
0 if successful or -1 if an error happened.
long xdl_read_mmfile(mmfile_t *mmf, void *data, long size);
Request to read size bytes from the memory file mmf by storing
the data inside the data buffer. Returns the number of bytes
read into the data buffer. The amount of data read can be lower
than the specified size. The function returns -1 if an error
happened.
long xdl_write_mmfile(mmfile_t *mmf, void const *data, long size);
Request to write size bytes from the specified buffer data into
the memory file mmf. If the memory file has been created using
the XDL_MMF_ATOMIC flag, the write request will not be split
across different blocks. Note that all write operations done on
memory files do append data at the end the file, and writes in
the middle of it are allowed. This is because the library memory
file abstraction does not need this functionality to be avail-
able. The function returns the number of bytes written or a
number lower than size if an error happened.
long xdl_writem_mmfile(mmfile_t *mmf, mmbuffer_t *mb, int nbuf);
Request to sequentially write nbuf memory buffers passed inside
the array mb into the memory file mmf. The memory buffer struc-
ture is defined as :
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
The ptr field is a pointer to the user data, whose size is spec-
ified inside the size structure field. The function returns the
total number of bytes written or a lower number if an error hap-
pened.
void *xdl_mmfile_writeallocate(mmfile_t *mmf, long size);
The function request to allocate a write buffer of size bytes in
the mmf memory file and returns the pointer to the allocated
buffer. The user will have the responsibility to store size
bytes (no more, no less) inside the memory region pointed to by
the returned pointer. The files size will grow of size bytes as
a consequence of this operation. The function will return NULL
if an error happened.
long xdl_mmfile_ptradd(mmfile_t *mmf, char *ptr, long size, unsigned
long flags);
The function adds a user specified block to the end of the mem-
ory file mmf. The block first byte is pointed to by ptr and its
length is size bytes. The flags parameter can be used to specify
attributes of the user memory block. Currently supported
attributes are:
XDL_MMB_READONLY Specify that the added memory block must be
treated as read-only, and every attempt to write on it should
result in a failure of the memory file writing functions.
The purpose of this function is basically to avoid copying mem-
ory around, by helping the library to not drain the CPU cache.
The function returns size in case of success, or -1 in case of
error.
void *xdl_mmfile_first(mmfile_t *mmf, long *size);
The function is used to return the first block of the mmf memory
file block chain. The size parameter will receive the size of
the block, while the function will return the pointer the the
first byte of the block itself. The function returns NULL if the
file is empty.
void *xdl_mmfile_next(mmfile_t *mmf, long *size);
The function is used to return the next block of the mmf memory
file block chain. The size parameter will receive the size of
the block, while the function will return the pointer the the
first byte of the block itself. The function returns NULL if the
current block is the last one of the chain.
long xdl_mmfile_size(mmfile_t *mmf);
The function returns the size of the specified memory file mmf.
int xdl_mmfile_cmp(mmfile_t *mmf1, mmfile_t *mmf2);
Request to compare two memory files mmf1 and mmf2 and returns 0
if files are identical, or a value different from 0 if files are
different.
int xdl_mmfile_compact(mmfile_t *mmfo, mmfile_t *mmfc, long bsize,
unsigned long flags);
Request to create a compact version of the memory file mmfo into
the (uninitialized) memory file mmfc. The bsize parameter spec-
ify the requested block size and flags specify flags to be used
to create the new mmfc memory file (see xdl_init_mmfile() ). The
function returns 0 if succedded or -1 if an error happened.
int xdl_diff(mmfile_t *mmf1, mmfile_t *mmf2, xpparam_t const *xpp,
xdemitconf_t const *xecfg, xdemitcb_t *ecb);
Request to create the difference between the two text memory
files mmf1 and mmf2. The mmf1 memory files is considered the
"old" file while mmf2 is considered the "new" file. So the func-
tion will create a patch file that once applied to mmf1 will
give mmf2 as result. Files mmf1 and mmf2 must be atomic from a
line point of view (or, as an extreme, compact), that means that
a single test line cannot spread among different memory file
blocks. The xpp parameter is a pointer to a structure :
typedef struct s_xpparam {
unsigned long flags;
} xpparam_t;
that is used to specify parameters to be used by the file dif-
ferential algorithm. The flags field is a combination of the
following flags :
XDF_NEED_MINIMAL Requires the minimal edit script to be found by
the algorithm (may be slow).
The xecfg parameter point to a structure :
typedef struct s_xdemitconf {
long ctxlen;
} xdemitconf_t;
that is used to configure the algorithm responsible of the
creation the the differential file from an edit script. The
ctxlen field is used to specify the amount of context to be
emitted inside the differential file (the value 3 is suggested
for normal operations). The parameter ecb is a pointer to a
structure :
typedef struct s_xdemitcb {
void *priv;
int (*outf)(void *, mmbuffer_t *, int);
} xdemitcb_t;
that is used by the differential file creation algorithm to emit
the created data. The priv field is an opaque pointer to a user
specified data, while the outf field point to a callback func-
tion that is called internally to emit algorithm generated data
rappresenting the differential file. The first parameter of the
callback is the same priv field specified inside the xdemitcb_t
structure. The second parameter point to an array of mmbuffer_t
(see above for a definition of the structure) whose element
count is specified inside the last parameter of the callback
itself. The callback will always be called with entire records
(lines) and never a record (line) will be emitted using two dif-
ferent callback calls. This is important because if the called
will use another memory file to store the result, by creating
the target memory file with XDL_MMF_ATOMIC will guarantee the
"atomicity" of the memory file itself. The function returns 0
if succeeded or -1 if an error occurred.
int xdl_patch(mmfile_t *mmf, mmfile_t *mmfp, int mode, xdemitcb_t *ecb,
xdemitcb_t *rjecb);
Request to patch the memory file mmf using the patch file stored
in mmfp. The mmf memory file is not changed during the opera-
tion and can be considered as read only. The mode parameter can
be one of the following values :
XDL_PATCH_NORMAL Perform standard patching like if the patch
memory file mmfp has been created using mmf as "old" file.
XDL_PATCH_REVERSE Apply the reverse patch. That means that the
mmf memory file has to be considered as if it was specified as
"new" file during the differential operation ( xdl_diff() ). The
result of the operation will then be the file content that was
used as "old" file during the differential operation.
The following flags can be specified (by or-ing them) to one of
the above:
XDL_PATCH_IGNOREBSPACE Ignore the whitespace at the beginning
and the end of the line.
The ecb will be used by the patch algorithm to create the result
file while the rjecb will be used to emit all differential
chunks that cannot be applied. Like explained above, callbacks
are always called with entire records to guarantee atomicity of
the resulting output. The function returns 0 if succeeded with-
out performing any fuzzy hunk detection, a positive value if it
secceeded with fuzzy hunk detection or -1 if an error occurred
during the patch operation.
int xdl_merge3(mmfile_t *mmfo, mmfile_t *mmf1, mmfile_t *mmf2,
xdemitcb_t *ecb, xdemitcb_t *rjecb);
Merges three files together. The mmfo file is the original one,
while mmf1 and mmf2 are two modified versions of mmfo. The
function works by creating a differential between mmfo and mmf2
and by applying the resulting patch to mmf1. Because of this
sequence, mmf1 changes will be privileged against the ones of
mmf2. The ecb will be used by the patch algorithm to create the
result file while the rjecb will be used to emit all differen-
tial chunks that cannot be applied. Like explained above, call-
backs are always called with entire records to guarantee atomic-
ity of the resulting output. The function returns 0 if suc-
ceeded or -1 if an error occurred during the patch operation.
int xdl_bdiff(mmfile_t *mmf1, mmfile_t *mmf2, bdiffparam_t const *bdp,
xdemitcb_t *ecb);
Request to create the difference between the two text memory
files mmf1 and mmf2. The mmf1 memory files is considered the
"old" file while mmf2 is considered the "new" file. So the func-
tion will create a patch file that once applied to mmf1 will
give mmf2 as result. Files mmf1 and mmf2 must be compact to make
it easy and faster to perform the difference operation. Func-
tions are available to check for compactness ( xdl_mmfile_iscom-
pact() ) and to make compact a non-compact file (
xdl_mmfile_compact() ). An example of how to create a compact
memory file (described inside the test subdirectory) is :
int xdlt_load_mmfile(char const *fname, mmfile_t *mf, int binmode) {
char cc;
int fd;
long size, bsize;
char *blk;
if (xdl_init_mmfile(mf, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0)
return -1;
if ((fd = open(fname, O_RDONLY)) == -1) {
perror(fname);
xdl_free_mmfile(mf);
return -1;
}
if ((size = bsize = lseek(fd, 0, SEEK_END)) > 0 && !binmode) {
if (lseek(fd, -1, SEEK_END) != (off_t) -1 &&
read(fd, &cc, 1) && cc != '\n')
bsize++;
}
lseek(fd, 0, SEEK_SET);
if (!(blk = (char *) xdl_mmfile_writeallocate(mf, bsize))) {
xdl_free_mmfile(mf);
close(fd);
return -1;
}
if (read(fd, blk, (size_t) size) != (size_t) size) {
perror(fname);
xdl_free_mmfile(mf);
close(fd);
return -1;
}
close(fd);
if (bsize > size)
blk[size] = '\n';
return 0;
}
The bdp parameter points to a structure :
typedef struct s_bdiffparam {
long bsize;
} bdiffparam_t;
that is used to pass information to the binary file differential
algorithm. The bsize parameter specify the size of the block
that will be used to decompose mmf1 during the block classifica-
tion phase of the algorithm (see MacDonald paper). Suggested
values go from 16 to 64, with a preferred power of two charac-
teristic. The ecb parameter is used to pass the emission call-
back to the algorithm responsible of the output file creation.
The function returns 0 if succeede or -1 if an error is
occurred.
int xdl_bdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, bdiffparam_t const
*bdp, xdemitcb_t *ecb);
Same as xdl_bdiff() but it works on memory buffer directly. The
xdl_bdiff() is implemented internally with a xdl_bdiff_mb()
after having setup the two memory buffers from the passed memory
files (that must be compact, as described above). The memory
buffer structure is defined as :
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
An empty memory buffer is specified by setting the ptr member as
NULL and the size member as zero. The reason of having this
function is to avoid the memory file preparation, that might
involve copying memory from other sources. Using the
xdl_bdiff_mb(), the caller can setup the two memory buffer by
using, for example, mmap(2), and hence avoiding unnecessary mem-
ory copies. The other parameters and the return value of the
function xdl_bdiff_mb() are the same as the ones already
described in xdl_bdiff().
int xdl_rabdiff(mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb);
Request to create the difference between the two text memory
files mmf1 and mmf2 using the Rabin's polynomial fingerprinting
algorithm. This algorithm typically performs faster and produces
smaller deltas, when compared to the XDelta-like one. The mmf1
memory files is considered the "old" file while mmf2 is consid-
ered the "new" file. So the function will create a patch file
that once applied to mmf1 will give mmf2 as result. Files mmf1
and mmf2 must be compact to make it easy and faster to perform
the difference operation. Functions are available to check for
compactness ( xdl_mmfile_iscompact() ) and to make compact a
non-compact file ( xdl_mmfile_compact() ). The ecb parameter is
used to pass the emission callback to the algorithm responsible
of the output file creation. The function returns 0 if succeede
or -1 if an error is occurred.
int xdl_rabdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, xdemitcb_t
*ecb);
Same as xdl_rabdiff() but it works on memory buffer directly.
The memory buffer structure is defined as :
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
An empty memory buffer is specified by setting the ptr member as
NULL and the size member as zero. The reason of having this
function is to avoid the memory file preparation, that might
involve copying memory from other sources. Using the xdl_rabd-
iff_mb(), the caller can setup the two memory buffer by using,
for example, mmap(2), and hence avoiding unnecessary memory
copies. The other parameters and the return value of the func-
tion xdl_rabdiff_mb() are the same as the ones already described
in xdl_rabdiff().
long xdl_bdiff_tgsize(mmfile_t *mmfp);
Given a binary memory file patch, it returns the size that the
result file will have once the patch is applied to the target
file. It can be used to pre-allocate (or write-allocate) a mem-
ory block to store the patch result so that a compact file will
be available at the end of the operation. The function returns
the requested size, or -1 if an error occurred during the opera-
tion.
int xdl_bpatch(mmfile_t *mmf, mmfile_t *mmfp, xdemitcb_t *ecb);
Request to patch the binary memory file mmf using the binary
patch file stored in mmfp. The mmf memory file is not changed
during the operation and can be considered as read only. The
binary patch algorithm has no notion of context, so the patch
operation cannot be partial (either success or failure). The ecb
parameter contain the callabck (see above for description) used
by the binary patch algorithm to emit the result file. The func-
tion returns 0 if succeeded or -1 if an error occurred during
the patch operation.
SEE ALSO
Two papers drove the content of this library and these are :
o File System Support for Delta Compression by Joshua P. MacDonald
http://www.xmailserver.org/xdfs.pdf
o Fingerprinting by Random Polynomials by Michael O. Rabin
http://www.xmailserver.org/rabin.pdf
o An O(ND) Difference Algorithm and Its Variations by Eugene W.
Myers http://www.xmailserver.org/diff2.pdf
Also usefull information can be looked up inside the diffutil GNU pack-
age :
http://www.gnu.org/software/diffutils/diffutils.html
LICENSE
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. A copy of the license is available
at :
http://www.gnu.org/copyleft/lesser.html
AUTHOR
Developed by Davide Libenzi <davidel@xmailserver.org>
AVAILABILITY
The latest version of LibXDiff can be found at :
http://www.xmailserver.org/xdiff-lib.html
BUGS
There are no known bugs. Bug reports and comments to Davide Libenzi
<davidel@xmailserver.org>
GNU 0.23 LibXDiff(3)

360
src/libxdiff/missing Executable file
View File

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

158
src/libxdiff/mkinstalldirs Executable file
View File

@ -0,0 +1,158 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2005-06-29.22
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
errstatus=0
dirmode=
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
for d
do
test "x$d" = x && continue
pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp=$pathcomp/
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

1
src/libxdiff/stamp-h Normal file
View File

@ -0,0 +1 @@
timestamp

0
src/libxdiff/stamp-h.in Normal file
View File

View File

@ -0,0 +1,10 @@
noinst_PROGRAMS = xrabin32 xrabin64
xrabin32_SOURCES = xrabin.c
xrabin32_CFLAGS = -DXRAB_WORD_TYPE=int -DXRAB_WORD_PFMT=\"0x%x\"
xrabin64_SOURCES = xrabin.c
xrabin64_CFLAGS = -DXRAB_WORD_TYPE="long long" -DXRAB_WORD_PFMT=\"0x%llx\"

View File

@ -0,0 +1,463 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = xrabin32$(EXEEXT) xrabin64$(EXEEXT)
subdir = tools
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_xrabin32_OBJECTS = xrabin32-xrabin.$(OBJEXT)
xrabin32_OBJECTS = $(am_xrabin32_OBJECTS)
xrabin32_LDADD = $(LDADD)
am_xrabin64_OBJECTS = xrabin64-xrabin.$(OBJEXT)
xrabin64_OBJECTS = $(am_xrabin64_OBJECTS)
xrabin64_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(xrabin32_SOURCES) $(xrabin64_SOURCES)
DIST_SOURCES = $(xrabin32_SOURCES) $(xrabin64_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
xrabin32_SOURCES = xrabin.c
xrabin32_CFLAGS = -DXRAB_WORD_TYPE=int -DXRAB_WORD_PFMT=\"0x%x\"
xrabin64_SOURCES = xrabin.c
xrabin64_CFLAGS = -DXRAB_WORD_TYPE="long long" -DXRAB_WORD_PFMT=\"0x%llx\"
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu tools/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
xrabin32$(EXEEXT): $(xrabin32_OBJECTS) $(xrabin32_DEPENDENCIES)
@rm -f xrabin32$(EXEEXT)
$(LINK) $(xrabin32_LDFLAGS) $(xrabin32_OBJECTS) $(xrabin32_LDADD) $(LIBS)
xrabin64$(EXEEXT): $(xrabin64_OBJECTS) $(xrabin64_DEPENDENCIES)
@rm -f xrabin64$(EXEEXT)
$(LINK) $(xrabin64_LDFLAGS) $(xrabin64_OBJECTS) $(xrabin64_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xrabin32-xrabin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xrabin64-xrabin.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
xrabin32-xrabin.o: xrabin.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin32_CFLAGS) $(CFLAGS) -MT xrabin32-xrabin.o -MD -MP -MF "$(DEPDIR)/xrabin32-xrabin.Tpo" -c -o xrabin32-xrabin.o `test -f 'xrabin.c' || echo '$(srcdir)/'`xrabin.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xrabin32-xrabin.Tpo" "$(DEPDIR)/xrabin32-xrabin.Po"; else rm -f "$(DEPDIR)/xrabin32-xrabin.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xrabin.c' object='xrabin32-xrabin.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin32_CFLAGS) $(CFLAGS) -c -o xrabin32-xrabin.o `test -f 'xrabin.c' || echo '$(srcdir)/'`xrabin.c
xrabin32-xrabin.obj: xrabin.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin32_CFLAGS) $(CFLAGS) -MT xrabin32-xrabin.obj -MD -MP -MF "$(DEPDIR)/xrabin32-xrabin.Tpo" -c -o xrabin32-xrabin.obj `if test -f 'xrabin.c'; then $(CYGPATH_W) 'xrabin.c'; else $(CYGPATH_W) '$(srcdir)/xrabin.c'; fi`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xrabin32-xrabin.Tpo" "$(DEPDIR)/xrabin32-xrabin.Po"; else rm -f "$(DEPDIR)/xrabin32-xrabin.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xrabin.c' object='xrabin32-xrabin.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin32_CFLAGS) $(CFLAGS) -c -o xrabin32-xrabin.obj `if test -f 'xrabin.c'; then $(CYGPATH_W) 'xrabin.c'; else $(CYGPATH_W) '$(srcdir)/xrabin.c'; fi`
xrabin64-xrabin.o: xrabin.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin64_CFLAGS) $(CFLAGS) -MT xrabin64-xrabin.o -MD -MP -MF "$(DEPDIR)/xrabin64-xrabin.Tpo" -c -o xrabin64-xrabin.o `test -f 'xrabin.c' || echo '$(srcdir)/'`xrabin.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xrabin64-xrabin.Tpo" "$(DEPDIR)/xrabin64-xrabin.Po"; else rm -f "$(DEPDIR)/xrabin64-xrabin.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xrabin.c' object='xrabin64-xrabin.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin64_CFLAGS) $(CFLAGS) -c -o xrabin64-xrabin.o `test -f 'xrabin.c' || echo '$(srcdir)/'`xrabin.c
xrabin64-xrabin.obj: xrabin.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin64_CFLAGS) $(CFLAGS) -MT xrabin64-xrabin.obj -MD -MP -MF "$(DEPDIR)/xrabin64-xrabin.Tpo" -c -o xrabin64-xrabin.obj `if test -f 'xrabin.c'; then $(CYGPATH_W) 'xrabin.c'; else $(CYGPATH_W) '$(srcdir)/xrabin.c'; fi`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xrabin64-xrabin.Tpo" "$(DEPDIR)/xrabin64-xrabin.Po"; else rm -f "$(DEPDIR)/xrabin64-xrabin.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xrabin.c' object='xrabin64-xrabin.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xrabin64_CFLAGS) $(CFLAGS) -c -o xrabin64-xrabin.obj `if test -f 'xrabin.c'; then $(CYGPATH_W) 'xrabin.c'; else $(CYGPATH_W) '$(srcdir)/xrabin.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

296
src/libxdiff/tools/xrabin.c Normal file
View File

@ -0,0 +1,296 @@
/*
* xrabin by Davide Libenzi (Rabin's polynomial generator)
* Copyright (C) 2006 Davide Libenzi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*
* Hints, ideas and code for the implementation came from:
*
* Rabin's original paper: http://www.xmailserver.org/rabin.pdf
* Chan & Lu's paper: http://www.xmailserver.org/rabin_impl.pdf
* Broder's paper: http://www.xmailserver.org/rabin_apps.pdf
* LBFS source code: http://www.fs.net/sfswww/lbfs/
* Geert Bosch's post: http://marc.theaimsgroup.com/?l=git&m=114565424620771&w=2
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined(WIN32)
#define strtoll _strtoi64
#endif
#if !defined(XRAB_WORD_TYPE)
#if defined(WIN32)
#define XRAB_WORD_TYPE __int64
#else /* #if defined(WIN32) */
#define XRAB_WORD_TYPE long long
#endif /* #if defined(WIN32) */
#endif /* #if !defined(XRAB_WORD_TYPE) */
#if !defined(XRAB_WORD_PFMT)
#if defined(WIN32)
#define XRAB_WORD_PFMT "0x%I64x"
#else /* #if defined(WIN32) */
#define XRAB_WORD_PFMT "0x%llx"
#endif /* #if defined(WIN32) */
#endif /* #if !defined(XRAB_WORD_PFMT) */
#define XPLYW_BITS (sizeof(xply_word) * 8)
#define XPLYW_MSB ((xply_word) 1 << (sizeof(xply_word) * 8 - 1))
typedef unsigned XRAB_WORD_TYPE xply_word;
static int xrab_isprime(int n) {
if (n > 3) {
if (n & 1) {
int i, hn = n / 2;
for (i = 3; i < hn; i += 2)
if (!(n % i))
return 0;
} else
return 0;
}
return 1;
}
static int xrab_fls(xply_word v) {
int r, s;
xply_word mask = ~(((xply_word) 1 << (XPLYW_BITS / 2)) - 1);
if (v == 0)
return 0;
for (r = XPLYW_BITS, s = r / 2; s != 0;) {
if ((v & mask) == 0) {
v <<= s;
r -= s;
}
s /= 2;
mask <<= s;
}
return r;
}
static xply_word xrab_polymod(xply_word nh, xply_word nl, xply_word d) {
int i, k = xrab_fls(d) - 1;
d <<= (XPLYW_BITS - 1) - k;
if (nh) {
if (nh & XPLYW_MSB)
nh ^= d;
for (i = XPLYW_BITS - 2; i >= 0; i--)
if (nh & ((xply_word) 1) << i) {
nh ^= d >> (XPLYW_BITS - 1) - i;
nl ^= d << i + 1;
}
}
for (i = XPLYW_BITS - 1; i >= k; i--)
if (nl & ((xply_word) 1 << i))
nl ^= d >> (XPLYW_BITS - 1) - i;
return nl;
}
static xply_word xrab_polygcd(xply_word x, xply_word y) {
for (;;) {
if (!y)
return x;
x = xrab_polymod(0, x, y);
if (!x)
return y;
y = xrab_polymod(0, y, x);
}
}
static void xrab_polymult(xply_word *php, xply_word *plp, xply_word x,
xply_word y) {
int i;
xply_word ph = 0, pl = 0;
if (x & 1)
pl = y;
for (i = 1; i < XPLYW_BITS; i++)
if (x & (((xply_word) 1) << i)) {
ph ^= y >> (XPLYW_BITS - i);
pl ^= y << i;
}
if (php)
*php = ph;
if (plp)
*plp = pl;
}
static xply_word xrab_polymmult(xply_word x, xply_word y, xply_word d) {
xply_word h, l;
xrab_polymult(&h, &l, x, y);
return xrab_polymod(h, l, d);
}
static int xrab_polyirreducible(xply_word f) {
xply_word u = 2;
int i, m = (xrab_fls(f) - 1) >> 1;
for (i = 0; i < m; i++) {
u = xrab_polymmult(u, u, f);
if (xrab_polygcd(f, u ^ 2) != 1)
return 0;
}
return 1;
}
static void xrab_rndgen(xply_word *f) {
unsigned int i;
xply_word g;
for (i = 0, g = 0; i < sizeof(xply_word); i++)
g ^= (g << 11) + (unsigned int) rand() + (g >> 7);
*f = g;
}
static int xrab_polygen(int degree, xply_word *ply) {
xply_word msb, mask, f;
if (degree <= 0 || degree >= XPLYW_BITS)
return -1;
msb = ((xply_word) 1) << degree;
mask = msb - 1;
srand(time(NULL));
do {
xrab_rndgen(&f);
f = (f & mask) | msb;
} while (!xrab_polyirreducible(f));
*ply = f;
return 0;
}
static int xarb_calc_tu(xply_word poly, int size, xply_word *t, xply_word *u) {
int j, xshift, shift;
xply_word t1, ssh;
xshift = xrab_fls(poly) - 1;
shift = xshift - 8;
if (shift < 0)
return -1;
t1 = xrab_polymod(0, ((xply_word) 1) << xshift, poly);
for (j = 0; j < 256; j++)
t[j] = xrab_polymmult(j, t1, poly) | ((xply_word) j << xshift);
for (j = 1, ssh = 1; j < size; j++)
ssh = (ssh << 8) ^ t[ssh >> shift];
for (j = 0; j < 256; j++)
u[j] = xrab_polymmult(j, ssh, poly);
return 0;
}
int main(int ac, char **av) {
int i, size = 20, degree = 0, shift;
xply_word ply = 0, t[256], u[256];
for (i = 1; i < ac; i++) {
if (strcmp(av[i], "-s") == 0) {
if (++i < ac)
size = atol(av[i]);
} else if (strcmp(av[i], "-p") == 0) {
if (++i < ac)
ply = (xply_word) strtoll(av[i], NULL, 16);
} else if (strcmp(av[i], "-d") == 0) {
if (++i < ac)
degree = atol(av[i]);
}
}
if (degree && (degree < 8 || degree >= XPLYW_BITS)) {
fprintf(stderr, "degree (%d) out of bound for the poly word size (8..%u)\n",
degree, XPLYW_BITS);
return 1;
}
if (degree == 0)
for (degree = XPLYW_BITS - 1; !xrab_isprime(degree); degree--);
if (ply == 0 && xrab_polygen(degree, &ply) < 0)
return 2;
shift = (xrab_fls(ply) - 1) - 8;
fprintf(stderr, "found poly = " XRAB_WORD_PFMT " (shift %d)\n",
ply, shift);
if (xarb_calc_tu(ply, size, t, u) < 0)
return 3;
fprintf(stdout, "#if defined(XRABPLY_TYPE%d)\n\n", XPLYW_BITS);
fprintf(stdout, "#if !defined(XV%d)\n", XPLYW_BITS);
fprintf(stdout, "#define XV%d(v) ((xply_word) v ## ULL)\n", XPLYW_BITS);
fprintf(stdout, "#endif\n\n");
fprintf(stdout, "#define XRAB_ROOTPOLY XV%d(" XRAB_WORD_PFMT ")\n\n",
XPLYW_BITS, ply);
fprintf(stdout, "#define XRAB_SHIFT %d\n", shift);
fprintf(stdout, "#define XRAB_WNDSIZE %d\n\n", size);
fprintf(stdout, "typedef unsigned XRABPLY_TYPE%d xply_word;\n\n", XPLYW_BITS);
fprintf(stdout, "static const xply_word T[256] = {\n");
for (i = 0; i < 256; i++) {
if (i) {
fputs(",", stdout);
if (i % 4 == 0)
fputs("\n\t", stdout);
else
fputs(" ", stdout);
} else
fputs("\t", stdout);
fprintf(stdout, "XV%d(" XRAB_WORD_PFMT ")", XPLYW_BITS, t[i]);
}
fprintf(stdout, "\n};\n\n");
fprintf(stdout, "static const xply_word U[256] = {\n");
for (i = 0; i < 256; i++) {
if (i) {
fputs(",", stdout);
if (i % 4 == 0)
fputs("\n\t", stdout);
else
fputs(" ", stdout);
} else
fputs("\t", stdout);
fprintf(stdout, "XV%d(" XRAB_WORD_PFMT ")", XPLYW_BITS, u[i]);
}
fprintf(stdout, "\n};\n\n");
fprintf(stdout, "#endif /* if defined(XRABPLY_TYPE%d) */\n\n", XPLYW_BITS);
return 0;
}

46
src/libxdiff/winconfig.h Normal file
View File

@ -0,0 +1,46 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(WINCONFIG_H)
#define WINCONFIG_H
#if !defined(PACKAGE_VERSION)
#define PACKAGE_VERSION "0.23"
#endif /* #if !defined(PACKAGE_VERSION) */
#define HAVE_STDIO_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_LIMITS_H 1
#define HAVE_MEMCHR 1
#define HAVE_MEMCMP 1
#define HAVE_MEMCPY 1
#define HAVE_MEMSET 1
#define HAVE_STRLEN 1
#define XRABPLY_TYPE64 __int64
#define XV64(v) ((xply_word) v ## UI64)
#endif /* WINCONFIG_H */

View File

@ -0,0 +1,8 @@
include_HEADERS = xdiff.h
lib_LTLIBRARIES = libxdiff.la
libxdiff_la_SOURCES = xdiffi.c xprepare.c xpatchi.c xmerge3.c xemit.c xmissing.c xutils.c xadler32.c xbdiff.c \
xbpatchi.c xversion.c xalloc.c xrabdiff.c

View File

@ -0,0 +1,496 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = xdiff
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libxdiff_la_LIBADD =
am_libxdiff_la_OBJECTS = xdiffi.lo xprepare.lo xpatchi.lo xmerge3.lo \
xemit.lo xmissing.lo xutils.lo xadler32.lo xbdiff.lo \
xbpatchi.lo xversion.lo xalloc.lo xrabdiff.lo
libxdiff_la_OBJECTS = $(am_libxdiff_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libxdiff_la_SOURCES)
DIST_SOURCES = $(libxdiff_la_SOURCES)
includeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(include_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
include_HEADERS = xdiff.h
lib_LTLIBRARIES = libxdiff.la
libxdiff_la_SOURCES = xdiffi.c xprepare.c xpatchi.c xmerge3.c xemit.c xmissing.c xutils.c xadler32.c xbdiff.c \
xbpatchi.c xversion.c xalloc.c xrabdiff.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xdiff/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu xdiff/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libxdiff.la: $(libxdiff_la_OBJECTS) $(libxdiff_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libxdiff_la_LDFLAGS) $(libxdiff_la_OBJECTS) $(libxdiff_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xadler32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xalloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbdiff.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbpatchi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdiffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xemit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmerge3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmissing.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpatchi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xprepare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xrabdiff.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xutils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xversion.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
@list='$(include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
$(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(include_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
rm -f "$(DESTDIR)$(includedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-includeHEADERS
install-exec-am: install-libLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-includeHEADERS uninstall-info-am \
uninstall-libLTLIBRARIES
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-includeHEADERS install-info \
install-info-am install-libLTLIBRARIES install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-includeHEADERS uninstall-info-am \
uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,34 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the `memchr' function. */
#define HAVE_MEMCHR 1
/* Define to 1 if you have the `memcmp' function. */
#define HAVE_MEMCMP 1
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlen' function. */
#define HAVE_STRLEN 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.23"

View File

@ -0,0 +1,70 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
/* largest prime smaller than 65536 */
#define BASE 65521L
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define NMAX 5552
#define DO1(buf, i) { s1 += buf[i]; s2 += s1; }
#define DO2(buf, i) DO1(buf, i); DO1(buf, i + 1);
#define DO4(buf, i) DO2(buf, i); DO2(buf, i + 2);
#define DO8(buf, i) DO4(buf, i); DO4(buf, i + 4);
#define DO16(buf) DO8(buf, 0); DO8(buf, 8);
unsigned long xdl_adler32(unsigned long adler, unsigned char const *buf,
unsigned int len) {
int k;
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
if (!buf)
return 1;
while (len > 0) {
k = len < NMAX ? len :NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0)
do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}

View File

@ -0,0 +1,34 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XADLER32_H)
#define XADLER32_H
unsigned long xdl_adler32(unsigned long adler, unsigned char const *buf,
unsigned int len);
#endif /* #if !defined(XADLER32_H) */

View File

@ -0,0 +1,51 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
static memallocator_t xmalt = {NULL, NULL, NULL};
int xdl_set_allocator(memallocator_t const *malt) {
xmalt = *malt;
return 0;
}
void *xdl_malloc(unsigned int size) {
return xmalt.malloc ? xmalt.malloc(xmalt.priv, size): NULL;
}
void xdl_free(void *ptr) {
if (xmalt.free)
xmalt.free(xmalt.priv, ptr);
}
void *xdl_realloc(void *ptr, unsigned int size) {
return xmalt.realloc ? xmalt.realloc(xmalt.priv, ptr, size): NULL;
}

315
src/libxdiff/xdiff/xbdiff.c Normal file
View File

@ -0,0 +1,315 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
typedef struct s_bdrecord {
struct s_bdrecord *next;
unsigned long fp;
char const *ptr;
} bdrecord_t;
typedef struct s_bdfile {
char const *data, *top;
chastore_t cha;
unsigned int fphbits;
bdrecord_t **fphash;
} bdfile_t;
static int xdl_prepare_bdfile(mmbuffer_t *mmb, long fpbsize, bdfile_t *bdf) {
unsigned int fphbits;
long i, size, hsize;
char const *base, *data, *top;
bdrecord_t *brec;
bdrecord_t **fphash;
fphbits = xdl_hashbits((unsigned int) (mmb->size / fpbsize) + 1);
hsize = 1 << fphbits;
if (!(fphash = (bdrecord_t **) xdl_malloc(hsize * sizeof(bdrecord_t *)))) {
return -1;
}
for (i = 0; i < hsize; i++)
fphash[i] = NULL;
if (xdl_cha_init(&bdf->cha, sizeof(bdrecord_t), hsize / 4 + 1) < 0) {
xdl_free(fphash);
return -1;
}
if (!(size = mmb->size)) {
bdf->data = bdf->top = NULL;
} else {
bdf->data = data = base = mmb->ptr;
bdf->top = top = mmb->ptr + mmb->size;
if ((data += (size / fpbsize) * fpbsize) == top)
data -= fpbsize;
for (; data >= base; data -= fpbsize) {
if (!(brec = (bdrecord_t *) xdl_cha_alloc(&bdf->cha))) {
xdl_cha_free(&bdf->cha);
xdl_free(fphash);
return -1;
}
brec->fp = xdl_adler32(0, (unsigned char const *) data,
XDL_MIN(fpbsize, (long) (top - data)));
brec->ptr = data;
i = (long) XDL_HASHLONG(brec->fp, fphbits);
brec->next = fphash[i];
fphash[i] = brec;
}
}
bdf->fphbits = fphbits;
bdf->fphash = fphash;
return 0;
}
static void xdl_free_bdfile(bdfile_t *bdf) {
xdl_free(bdf->fphash);
xdl_cha_free(&bdf->cha);
}
unsigned long xdl_mmb_adler32(mmbuffer_t *mmb) {
return mmb->size ? xdl_adler32(0, (unsigned char const *) mmb->ptr, mmb->size): 0;
}
unsigned long xdl_mmf_adler32(mmfile_t *mmf) {
unsigned long fp = 0;
long size;
char const *blk;
if ((blk = (char const *) xdl_mmfile_first(mmf, &size)) != NULL) {
do {
fp = xdl_adler32(fp, (unsigned char const *) blk, size);
} while ((blk = (char const *) xdl_mmfile_next(mmf, &size)) != NULL);
}
return fp;
}
int xdl_bdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, bdiffparam_t const *bdp, xdemitcb_t *ecb) {
long i, rsize, size, bsize, csize, msize, moff;
unsigned long fp;
char const *blk, *base, *data, *top, *ptr1, *ptr2;
bdrecord_t *brec;
bdfile_t bdf;
mmbuffer_t mb[2];
unsigned char cpybuf[32];
if ((bsize = bdp->bsize) < XDL_MIN_BLKSIZE)
bsize = XDL_MIN_BLKSIZE;
if (xdl_prepare_bdfile(mmb1, bsize, &bdf) < 0) {
return -1;
}
/*
* Prepare and emit the binary patch file header. It will be used
* to verify that that file being patched matches in size and fingerprint
* the one that generated the patch.
*/
fp = xdl_mmb_adler32(mmb1);
size = mmb1->size;
XDL_LE32_PUT(cpybuf, fp);
XDL_LE32_PUT(cpybuf + 4, size);
mb[0].ptr = (char *) cpybuf;
mb[0].size = 4 + 4;
if (ecb->outf(ecb->priv, mb, 1) < 0) {
xdl_free_bdfile(&bdf);
return -1;
}
if ((blk = (char const *) mmb2->ptr) != NULL) {
size = mmb2->size;
for (base = data = blk, top = data + size; data < top;) {
rsize = XDL_MIN(bsize, (long) (top - data));
fp = xdl_adler32(0, (unsigned char const *) data, rsize);
i = (long) XDL_HASHLONG(fp, bdf.fphbits);
for (msize = 0, brec = bdf.fphash[i]; brec; brec = brec->next)
if (brec->fp == fp) {
csize = XDL_MIN((long) (top - data), (long) (bdf.top - brec->ptr));
for (ptr1 = brec->ptr, ptr2 = data; csize && *ptr1 == *ptr2;
csize--, ptr1++, ptr2++);
if ((csize = (long) (ptr1 - brec->ptr)) > msize) {
moff = (long) (brec->ptr - bdf.data);
msize = csize;
}
}
if (msize < XDL_COPYOP_SIZE) {
data++;
} else {
if (data > base) {
i = (long) (data - base);
if (i > 255) {
cpybuf[0] = XDL_BDOP_INSB;
XDL_LE32_PUT(cpybuf + 1, i);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_INSBOP_SIZE;
} else {
cpybuf[0] = XDL_BDOP_INS;
cpybuf[1] = (unsigned char) i;
mb[0].ptr = (char *) cpybuf;
mb[0].size = 2;
}
mb[1].ptr = (char *) base;
mb[1].size = i;
if (ecb->outf(ecb->priv, mb, 2) < 0) {
xdl_free_bdfile(&bdf);
return -1;
}
}
data += msize;
cpybuf[0] = XDL_BDOP_CPY;
XDL_LE32_PUT(cpybuf + 1, moff);
XDL_LE32_PUT(cpybuf + 5, msize);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_COPYOP_SIZE;
if (ecb->outf(ecb->priv, mb, 1) < 0) {
xdl_free_bdfile(&bdf);
return -1;
}
base = data;
}
}
if (data > base) {
i = (long) (data - base);
if (i > 255) {
cpybuf[0] = XDL_BDOP_INSB;
XDL_LE32_PUT(cpybuf + 1, i);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_INSBOP_SIZE;
} else {
cpybuf[0] = XDL_BDOP_INS;
cpybuf[1] = (unsigned char) i;
mb[0].ptr = (char *) cpybuf;
mb[0].size = 2;
}
mb[1].ptr = (char *) base;
mb[1].size = i;
if (ecb->outf(ecb->priv, mb, 2) < 0) {
xdl_free_bdfile(&bdf);
return -1;
}
}
}
xdl_free_bdfile(&bdf);
return 0;
}
int xdl_bdiff(mmfile_t *mmf1, mmfile_t *mmf2, bdiffparam_t const *bdp, xdemitcb_t *ecb) {
mmbuffer_t mmb1, mmb2;
if (!xdl_mmfile_iscompact(mmf1) || !xdl_mmfile_iscompact(mmf2)) {
return -1;
}
if ((mmb1.ptr = (char *) xdl_mmfile_first(mmf1, &mmb1.size)) == NULL)
mmb1.size = 0;
if ((mmb2.ptr = (char *) xdl_mmfile_first(mmf2, &mmb2.size)) == NULL)
mmb2.size = 0;
return xdl_bdiff_mb(&mmb1, &mmb2, bdp, ecb);
}
long xdl_bdiff_tgsize(mmfile_t *mmfp) {
long tgsize = 0, size, off, csize;
char const *blk;
unsigned char const *data, *top;
if ((blk = (char const *) xdl_mmfile_first(mmfp, &size)) == NULL ||
size < XDL_BPATCH_HDR_SIZE) {
return -1;
}
blk += XDL_BPATCH_HDR_SIZE;
size -= XDL_BPATCH_HDR_SIZE;
do {
for (data = (unsigned char const *) blk, top = data + size;
data < top;) {
if (*data == XDL_BDOP_INS) {
data++;
csize = (long) *data++;
tgsize += csize;
data += csize;
} else if (*data == XDL_BDOP_INSB) {
data++;
XDL_LE32_GET(data, csize);
data += 4;
tgsize += csize;
data += csize;
} else if (*data == XDL_BDOP_CPY) {
data++;
XDL_LE32_GET(data, off);
data += 4;
XDL_LE32_GET(data, csize);
data += 4;
tgsize += csize;
} else {
return -1;
}
}
} while ((blk = (char const *) xdl_mmfile_next(mmfp, &size)) != NULL);
return tgsize;
}

View File

@ -0,0 +1,40 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XBDIFF_H)
#define XBDIFF_H
#define XDL_BPATCH_HDR_SIZE (4 + 4)
#define XDL_MIN_BLKSIZE 16
#define XDL_INSBOP_SIZE (1 + 4)
#define XDL_COPYOP_SIZE (1 + 4 + 4)
unsigned long xdl_mmb_adler32(mmbuffer_t *mmb);
unsigned long xdl_mmf_adler32(mmfile_t *mmf);
#endif /* #if !defined(XBDIFF_H) */

View File

@ -0,0 +1,336 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_MOBF_MINALLOC 128
typedef struct s_mmoffbuffer {
long off, size;
char *ptr;
} mmoffbuffer_t;
static int xdl_copy_range(mmfile_t *mmf, long off, long size, xdemitcb_t *ecb) {
if (xdl_seek_mmfile(mmf, off) < 0) {
return -1;
}
if (xdl_copy_mmfile(mmf, size, ecb) != size) {
return -1;
}
return 0;
}
int xdl_bpatch(mmfile_t *mmf, mmfile_t *mmfp, xdemitcb_t *ecb) {
long size, off, csize, osize;
unsigned long fp, ofp;
char const *blk;
unsigned char const *data, *top;
mmbuffer_t mb;
if ((blk = (char const *) xdl_mmfile_first(mmfp, &size)) == NULL ||
size < XDL_BPATCH_HDR_SIZE) {
return -1;
}
ofp = xdl_mmf_adler32(mmf);
osize = xdl_mmfile_size(mmf);
XDL_LE32_GET(blk, fp);
XDL_LE32_GET(blk + 4, csize);
if (fp != ofp || csize != osize) {
return -1;
}
blk += XDL_BPATCH_HDR_SIZE;
size -= XDL_BPATCH_HDR_SIZE;
do {
for (data = (unsigned char const *) blk, top = data + size;
data < top;) {
if (*data == XDL_BDOP_INS) {
data++;
mb.size = (long) *data++;
mb.ptr = (char *) data;
data += mb.size;
if (ecb->outf(ecb->priv, &mb, 1) < 0) {
return -1;
}
} else if (*data == XDL_BDOP_INSB) {
data++;
XDL_LE32_GET(data, csize);
data += 4;
mb.size = csize;
mb.ptr = (char *) data;
data += mb.size;
if (ecb->outf(ecb->priv, &mb, 1) < 0) {
return -1;
}
} else if (*data == XDL_BDOP_CPY) {
data++;
XDL_LE32_GET(data, off);
data += 4;
XDL_LE32_GET(data, csize);
data += 4;
if (xdl_copy_range(mmf, off, csize, ecb) < 0) {
return -1;
}
} else {
return -1;
}
}
} while ((blk = (char const *) xdl_mmfile_next(mmfp, &size)) != NULL);
return 0;
}
static unsigned long xdl_mmob_adler32(mmoffbuffer_t *obf, int n) {
unsigned long ha;
for (ha = 0; n > 0; n--, obf++)
ha = xdl_adler32(ha, (unsigned char const *) obf->ptr, obf->size);
return ha;
}
static long xdl_mmob_size(mmoffbuffer_t *obf, int n) {
return n > 0 ? obf[n - 1].off + obf[n - 1].size: 0;
}
static mmoffbuffer_t *xdl_mmob_new(mmoffbuffer_t **probf, int *pnobf, int *paobf) {
int aobf;
mmoffbuffer_t *cobf, *rrobf;
if (*pnobf >= *paobf) {
aobf = 2 * (*paobf) + 1;
if ((rrobf = (mmoffbuffer_t *)
xdl_realloc(*probf, aobf * sizeof(mmoffbuffer_t))) == NULL) {
return NULL;
}
*probf = rrobf;
*paobf = aobf;
}
cobf = (*probf) + (*pnobf);
(*pnobf)++;
return cobf;
}
static int xdl_mmob_find_cntr(mmoffbuffer_t *obf, int n, long off) {
int i, lo, hi;
for (lo = -1, hi = n; hi - lo > 1;) {
i = (hi + lo) / 2;
if (off < obf[i].off)
hi = i;
else
lo = i;
}
return (lo >= 0 && off >= obf[lo].off && off < obf[lo].off + obf[lo].size) ? lo: -1;
}
static int xdl_bmerge(mmoffbuffer_t *obf, int n, mmbuffer_t *mbfp, mmoffbuffer_t **probf,
int *pnobf) {
int i, aobf, nobf;
long ooff, off, csize;
unsigned long fp, ofp;
unsigned char const *data, *top;
mmoffbuffer_t *robf, *cobf;
if (mbfp->size < XDL_BPATCH_HDR_SIZE) {
return -1;
}
data = (unsigned char const *) mbfp->ptr;
top = data + mbfp->size;
ofp = xdl_mmob_adler32(obf, n);
XDL_LE32_GET(data, fp);
data += 4;
XDL_LE32_GET(data, csize);
data += 4;
if (fp != ofp || csize != xdl_mmob_size(obf, n)) {
return -1;
}
aobf = XDL_MOBF_MINALLOC;
nobf = 0;
if ((robf = (mmoffbuffer_t *) xdl_malloc(aobf * sizeof(mmoffbuffer_t))) == NULL) {
return -1;
}
for (ooff = 0; data < top;) {
if (*data == XDL_BDOP_INS) {
data++;
if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {
xdl_free(robf);
return -1;
}
cobf->off = ooff;
cobf->size = (long) *data++;
cobf->ptr = (char *) data;
data += cobf->size;
ooff += cobf->size;
} else if (*data == XDL_BDOP_INSB) {
data++;
XDL_LE32_GET(data, csize);
data += 4;
if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {
xdl_free(robf);
return -1;
}
cobf->off = ooff;
cobf->size = csize;
cobf->ptr = (char *) data;
data += cobf->size;
ooff += cobf->size;
} else if (*data == XDL_BDOP_CPY) {
data++;
XDL_LE32_GET(data, off);
data += 4;
XDL_LE32_GET(data, csize);
data += 4;
if ((i = xdl_mmob_find_cntr(obf, n, off)) < 0) {
xdl_free(robf);
return -1;
}
off -= obf[i].off;
for (; i < n && csize > 0; i++, off = 0) {
if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {
xdl_free(robf);
return -1;
}
cobf->off = ooff;
cobf->size = XDL_MIN(csize, obf[i].size - off);
cobf->ptr = obf[i].ptr + off;
ooff += cobf->size;
csize -= cobf->size;
}
if (csize > 0) {
xdl_free(robf);
return -1;
}
} else {
xdl_free(robf);
return -1;
}
}
*probf = robf;
*pnobf = nobf;
return 0;
}
static int xdl_bmerge_synt(mmoffbuffer_t *obf, int n, xdemitcb_t *ecb) {
int i;
mmbuffer_t *mb;
if ((mb = (mmbuffer_t *) xdl_malloc(n * sizeof(mmbuffer_t))) == NULL) {
return -1;
}
for (i = 0; i < n; i++) {
mb[i].ptr = obf[i].ptr;
mb[i].size = obf[i].size;
}
if (ecb->outf(ecb->priv, mb, n) < 0) {
xdl_free(mb);
return -1;
}
xdl_free(mb);
return 0;
}
int xdl_bpatch_multi(mmbuffer_t *base, mmbuffer_t *mbpch, int n, xdemitcb_t *ecb) {
int i, nobf, fnobf;
mmoffbuffer_t *obf, *fobf;
nobf = 1;
if ((obf = (mmoffbuffer_t *) xdl_malloc(nobf * sizeof(mmoffbuffer_t))) == NULL) {
return -1;
}
obf->off = 0;
obf->ptr = base->ptr;
obf->size = base->size;
for (i = 0; i < n; i++) {
if (xdl_bmerge(obf, nobf, &mbpch[i], &fobf, &fnobf) < 0) {
xdl_free(obf);
return -1;
}
xdl_free(obf);
obf = fobf;
nobf = fnobf;
}
if (xdl_bmerge_synt(obf, nobf, ecb) < 0) {
xdl_free(obf);
return -1;
}
xdl_free(obf);
return 0;
}

135
src/libxdiff/xdiff/xdiff.h Normal file
View File

@ -0,0 +1,135 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XDIFF_H)
#define XDIFF_H
#ifdef __cplusplus
extern "C" {
#endif /* #ifdef __cplusplus */
#define XDF_NEED_MINIMAL (1 << 1)
#define XDL_PATCH_NORMAL '-'
#define XDL_PATCH_REVERSE '+'
#define XDL_PATCH_MODEMASK ((1 << 8) - 1)
#define XDL_PATCH_IGNOREBSPACE (1 << 8)
#define XDL_MMB_READONLY (1 << 0)
#define XDL_MMF_ATOMIC (1 << 0)
#define XDL_BDOP_INS 1
#define XDL_BDOP_CPY 2
#define XDL_BDOP_INSB 3
typedef struct s_memallocator {
void *priv;
void *(*malloc)(void *, unsigned int);
void (*free)(void *, void *);
void *(*realloc)(void *, void *, unsigned int);
} memallocator_t;
typedef struct s_mmblock {
struct s_mmblock *next;
unsigned long flags;
long size, bsize;
char *ptr;
} mmblock_t;
typedef struct s_mmfile {
unsigned long flags;
mmblock_t *head, *tail;
long bsize, fsize, rpos;
mmblock_t *rcur, *wcur;
} mmfile_t;
typedef struct s_mmbuffer {
char *ptr;
long size;
} mmbuffer_t;
typedef struct s_xpparam {
unsigned long flags;
} xpparam_t;
typedef struct s_xdemitcb {
void *priv;
int (*outf)(void *, mmbuffer_t *, int);
} xdemitcb_t;
typedef struct s_xdemitconf {
long ctxlen;
} xdemitconf_t;
typedef struct s_bdiffparam {
long bsize;
} bdiffparam_t;
int xdl_set_allocator(memallocator_t const *malt);
void *xdl_malloc(unsigned int size);
void xdl_free(void *ptr);
void *xdl_realloc(void *ptr, unsigned int size);
int xdl_init_mmfile(mmfile_t *mmf, long bsize, unsigned long flags);
void xdl_free_mmfile(mmfile_t *mmf);
int xdl_mmfile_iscompact(mmfile_t *mmf);
int xdl_seek_mmfile(mmfile_t *mmf, long off);
long xdl_read_mmfile(mmfile_t *mmf, void *data, long size);
long xdl_write_mmfile(mmfile_t *mmf, void const *data, long size);
long xdl_writem_mmfile(mmfile_t *mmf, mmbuffer_t *mb, int nbuf);
void *xdl_mmfile_writeallocate(mmfile_t *mmf, long size);
long xdl_mmfile_ptradd(mmfile_t *mmf, char *ptr, long size, unsigned long flags);
long xdl_copy_mmfile(mmfile_t *mmf, long size, xdemitcb_t *ecb);
void *xdl_mmfile_first(mmfile_t *mmf, long *size);
void *xdl_mmfile_next(mmfile_t *mmf, long *size);
long xdl_mmfile_size(mmfile_t *mmf);
int xdl_mmfile_cmp(mmfile_t *mmf1, mmfile_t *mmf2);
int xdl_mmfile_compact(mmfile_t *mmfo, mmfile_t *mmfc, long bsize, unsigned long flags);
int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdemitconf_t const *xecfg, xdemitcb_t *ecb);
int xdl_patch(mmfile_t *mf, mmfile_t *mfp, int mode, xdemitcb_t *ecb,
xdemitcb_t *rjecb);
int xdl_merge3(mmfile_t *mmfo, mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb,
xdemitcb_t *rjecb);
int xdl_bdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, bdiffparam_t const *bdp, xdemitcb_t *ecb);
int xdl_bdiff(mmfile_t *mmf1, mmfile_t *mmf2, bdiffparam_t const *bdp, xdemitcb_t *ecb);
int xdl_rabdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, xdemitcb_t *ecb);
int xdl_rabdiff(mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb);
long xdl_bdiff_tgsize(mmfile_t *mmfp);
int xdl_bpatch(mmfile_t *mmf, mmfile_t *mmfp, xdemitcb_t *ecb);
int xdl_bpatch_multi(mmbuffer_t *base, mmbuffer_t *mbpch, int n, xdemitcb_t *ecb);
#ifdef __cplusplus
}
#endif /* #ifdef __cplusplus */
#endif /* #if !defined(XDIFF_H) */

556
src/libxdiff/xdiff/xdiffi.c Normal file
View File

@ -0,0 +1,556 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_MAX_COST_MIN 256
#define XDL_HEUR_MIN_COST 256
#define XDL_LINE_MAX (long)((1UL << (8 * sizeof(long) - 1)) - 1)
#define XDL_SNAKE_CNT 20
#define XDL_K_HEUR 4
typedef struct s_xdpsplit {
long i1, i2;
int min_lo, min_hi;
} xdpsplit_t;
/*
* See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.
* Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
* the forward diagonal starting from (off1, off2) and the backward diagonal
* starting from (lim1, lim2). If the K values on the same diagonal crosses
* returns the furthest point of reach. We might end up having to expensive
* cases using this algorithm is full, so a little bit of heuristic is needed
* to cut the search and to return a suboptimal point.
*/
static long xdl_split(unsigned long const *ha1, long off1, long lim1,
unsigned long const *ha2, long off2, long lim2,
long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
xdalgoenv_t *xenv) {
long dmin = off1 - lim2, dmax = lim1 - off2;
long fmid = off1 - off2, bmid = lim1 - lim2;
long odd = (fmid - bmid) & 1;
long fmin = fmid, fmax = fmid;
long bmin = bmid, bmax = bmid;
long ec, d, i1, i2, prev1, best, dd, v, k;
/*
* Set initial diagonal values for both forward and backward path.
*/
kvdf[fmid] = off1;
kvdb[bmid] = lim1;
for (ec = 1;; ec++) {
int got_snake = 0;
/*
* We need to extent the diagonal "domain" by one. If the next
* values exits the box boundaries we need to change it in the
* opposite direction because (max - min) must be a power of two.
* Also we initialize the extenal K value to -1 so that we can
* avoid extra conditions check inside the core loop.
*/
if (fmin > dmin)
kvdf[--fmin - 1] = -1;
else
++fmin;
if (fmax < dmax)
kvdf[++fmax + 1] = -1;
else
--fmax;
for (d = fmax; d >= fmin; d -= 2) {
if (kvdf[d - 1] >= kvdf[d + 1])
i1 = kvdf[d - 1] + 1;
else
i1 = kvdf[d + 1];
prev1 = i1;
i2 = i1 - d;
for (; i1 < lim1 && i2 < lim2 && ha1[i1] == ha2[i2]; i1++, i2++);
if (i1 - prev1 > xenv->snake_cnt)
got_snake = 1;
kvdf[d] = i1;
if (odd && bmin <= d && d <= bmax && kvdb[d] <= i1) {
spl->i1 = i1;
spl->i2 = i2;
spl->min_lo = spl->min_hi = 1;
return ec;
}
}
/*
* We need to extent the diagonal "domain" by one. If the next
* values exits the box boundaries we need to change it in the
* opposite direction because (max - min) must be a power of two.
* Also we initialize the extenal K value to -1 so that we can
* avoid extra conditions check inside the core loop.
*/
if (bmin > dmin)
kvdb[--bmin - 1] = XDL_LINE_MAX;
else
++bmin;
if (bmax < dmax)
kvdb[++bmax + 1] = XDL_LINE_MAX;
else
--bmax;
for (d = bmax; d >= bmin; d -= 2) {
if (kvdb[d - 1] < kvdb[d + 1])
i1 = kvdb[d - 1];
else
i1 = kvdb[d + 1] - 1;
prev1 = i1;
i2 = i1 - d;
for (; i1 > off1 && i2 > off2 && ha1[i1 - 1] == ha2[i2 - 1]; i1--, i2--);
if (prev1 - i1 > xenv->snake_cnt)
got_snake = 1;
kvdb[d] = i1;
if (!odd && fmin <= d && d <= fmax && i1 <= kvdf[d]) {
spl->i1 = i1;
spl->i2 = i2;
spl->min_lo = spl->min_hi = 1;
return ec;
}
}
if (need_min)
continue;
/*
* If the edit cost is above the heuristic trigger and if
* we got a good snake, we sample current diagonals to see
* if some of the, have reached an "interesting" path. Our
* measure is a function of the distance from the diagonal
* corner (i1 + i2) penalized with the distance from the
* mid diagonal itself. If this value is above the current
* edit cost times a magic factor (XDL_K_HEUR) we consider
* it interesting.
*/
if (got_snake && ec > xenv->heur_min) {
for (best = 0, d = fmax; d >= fmin; d -= 2) {
dd = d > fmid ? d - fmid: fmid - d;
i1 = kvdf[d];
i2 = i1 - d;
v = (i1 - off1) + (i2 - off2) - dd;
if (v > XDL_K_HEUR * ec && v > best &&
off1 + xenv->snake_cnt <= i1 && i1 < lim1 &&
off2 + xenv->snake_cnt <= i2 && i2 < lim2) {
for (k = 1; ha1[i1 - k] == ha2[i2 - k]; k++)
if (k == xenv->snake_cnt) {
best = v;
spl->i1 = i1;
spl->i2 = i2;
break;
}
}
}
if (best > 0) {
spl->min_lo = 1;
spl->min_hi = 0;
return ec;
}
for (best = 0, d = bmax; d >= bmin; d -= 2) {
dd = d > bmid ? d - bmid: bmid - d;
i1 = kvdb[d];
i2 = i1 - d;
v = (lim1 - i1) + (lim2 - i2) - dd;
if (v > XDL_K_HEUR * ec && v > best &&
off1 < i1 && i1 <= lim1 - xenv->snake_cnt &&
off2 < i2 && i2 <= lim2 - xenv->snake_cnt) {
for (k = 0; ha1[i1 + k] == ha2[i2 + k]; k++)
if (k == xenv->snake_cnt - 1) {
best = v;
spl->i1 = i1;
spl->i2 = i2;
break;
}
}
}
if (best > 0) {
spl->min_lo = 0;
spl->min_hi = 1;
return ec;
}
}
/*
* Enough is enough. We spent too much time here and now we collect
* the furthest reaching path using the (i1 + i2) measure.
*/
if (ec >= xenv->mxcost) {
long fbest, fbest1, bbest, bbest1;
fbest = -1;
for (d = fmax; d >= fmin; d -= 2) {
i1 = XDL_MIN(kvdf[d], lim1);
i2 = i1 - d;
if (lim2 < i2)
i1 = lim2 + d, i2 = lim2;
if (fbest < i1 + i2) {
fbest = i1 + i2;
fbest1 = i1;
}
}
bbest = XDL_LINE_MAX;
for (d = bmax; d >= bmin; d -= 2) {
i1 = XDL_MAX(off1, kvdb[d]);
i2 = i1 - d;
if (i2 < off2)
i1 = off2 + d, i2 = off2;
if (i1 + i2 < bbest) {
bbest = i1 + i2;
bbest1 = i1;
}
}
if ((lim1 + lim2) - bbest < fbest - (off1 + off2)) {
spl->i1 = fbest1;
spl->i2 = fbest - fbest1;
spl->min_lo = 1;
spl->min_hi = 0;
} else {
spl->i1 = bbest1;
spl->i2 = bbest - bbest1;
spl->min_lo = 0;
spl->min_hi = 1;
}
return ec;
}
}
return -1;
}
/*
* Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling
* the box splitting function. Note that the real job (marking changed lines)
* is done in the two boundary reaching checks.
*/
int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
diffdata_t *dd2, long off2, long lim2,
long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
/*
* Shrink the box by walking through each diagonal snake (SW and NE).
*/
for (; off1 < lim1 && off2 < lim2 && ha1[off1] == ha2[off2]; off1++, off2++);
for (; off1 < lim1 && off2 < lim2 && ha1[lim1 - 1] == ha2[lim2 - 1]; lim1--, lim2--);
/*
* If one dimension is empty, then all records on the other one must
* be obviously changed.
*/
if (off1 == lim1) {
char *rchg2 = dd2->rchg;
long *rindex2 = dd2->rindex;
for (; off2 < lim2; off2++)
rchg2[rindex2[off2]] = 1;
} else if (off2 == lim2) {
char *rchg1 = dd1->rchg;
long *rindex1 = dd1->rindex;
for (; off1 < lim1; off1++)
rchg1[rindex1[off1]] = 1;
} else {
long ec;
xdpsplit_t spl;
/*
* Divide ...
*/
if ((ec = xdl_split(ha1, off1, lim1, ha2, off2, lim2, kvdf, kvdb,
need_min, &spl, xenv)) < 0) {
return -1;
}
/*
* ... et Impera.
*/
if (xdl_recs_cmp(dd1, off1, spl.i1, dd2, off2, spl.i2,
kvdf, kvdb, spl.min_lo, xenv) < 0 ||
xdl_recs_cmp(dd1, spl.i1, lim1, dd2, spl.i2, lim2,
kvdf, kvdb, spl.min_hi, xenv) < 0) {
return -1;
}
}
return 0;
}
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *xe) {
long ndiags;
long *kvd, *kvdf, *kvdb;
xdalgoenv_t xenv;
diffdata_t dd1, dd2;
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
return -1;
}
/*
* Allocate and setup K vectors to be used by the differential algorithm.
* One is to store the forward path and one to store the backward path.
*/
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
xdl_free_env(xe);
return -1;
}
kvdf = kvd;
kvdb = kvdf + ndiags;
kvdf += xe->xdf2.nreff + 1;
kvdb += xe->xdf2.nreff + 1;
xenv.mxcost = xdl_bogosqrt(ndiags);
if (xenv.mxcost < XDL_MAX_COST_MIN)
xenv.mxcost = XDL_MAX_COST_MIN;
xenv.snake_cnt = XDL_SNAKE_CNT;
xenv.heur_min = XDL_HEUR_MIN_COST;
dd1.nrec = xe->xdf1.nreff;
dd1.ha = xe->xdf1.ha;
dd1.rchg = xe->xdf1.rchg;
dd1.rindex = xe->xdf1.rindex;
dd2.nrec = xe->xdf2.nreff;
dd2.ha = xe->xdf2.ha;
dd2.rchg = xe->xdf2.rchg;
dd2.rindex = xe->xdf2.rindex;
if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
xdl_free(kvd);
xdl_free_env(xe);
return -1;
}
xdl_free(kvd);
return 0;
}
static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
xdchange_t *xch;
if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
return NULL;
xch->next = xscr;
xch->i1 = i1;
xch->i2 = i2;
xch->chg1 = chg1;
xch->chg2 = chg2;
return xch;
}
static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) {
long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec;
char *rchg = xdf->rchg, *rchgo = xdfo->rchg;
xrecord_t **recs = xdf->recs;
/*
* This is the same of what GNU diff does. Move back and forward
* change groups for a consistent and pretty diff output. This also
* helps in finding joineable change groups and reduce the diff size.
*/
for (ix = ixo = 0;;) {
/*
* Find the first changed line in the to-be-compacted file.
* We need to keep track of both indexes, so if we find a
* changed lines group on the other file, while scanning the
* to-be-compacted file, we need to skip it properly. Note
* that loops that are testing for changed lines on rchg* do
* not need index bounding since the array is prepared with
* a zero at position -1 and N.
*/
for (; ix < nrec && !rchg[ix]; ix++)
while (rchgo[ixo++]);
if (ix == nrec)
break;
/*
* Record the start of a changed-group in the to-be-compacted file
* and find the end of it, on both to-be-compacted and other file
* indexes (ix and ixo).
*/
ixs = ix;
for (ix++; rchg[ix]; ix++);
for (; rchgo[ixo]; ixo++);
do {
grpsiz = ix - ixs;
/*
* If the line before the current change group, is equal to
* the last line of the current change group, shift backward
* the group.
*/
while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha &&
XDL_RECMATCH(recs[ixs - 1], recs[ix - 1])) {
rchg[--ixs] = 1;
rchg[--ix] = 0;
/*
* This change might have joined two change groups,
* so we try to take this scenario in account by moving
* the start index accordingly (and so the other-file
* end-of-group index).
*/
for (; rchg[ixs - 1]; ixs--);
while (rchgo[--ixo]);
}
/*
* Record the end-of-group position in case we are matched
* with a group of changes in the other file (that is, the
* change record before the enf-of-group index in the other
* file is set).
*/
ixref = rchgo[ixo - 1] ? ix: nrec;
/*
* If the first line of the current change group, is equal to
* the line next of the current change group, shift forward
* the group.
*/
while (ix < nrec && recs[ixs]->ha == recs[ix]->ha &&
XDL_RECMATCH(recs[ixs], recs[ix])) {
rchg[ixs++] = 0;
rchg[ix++] = 1;
/*
* This change might have joined two change groups,
* so we try to take this scenario in account by moving
* the start index accordingly (and so the other-file
* end-of-group index). Keep tracking the reference
* index in case we are shifting together with a
* corresponding group of changes in the other file.
*/
for (; rchg[ix]; ix++);
while (rchgo[++ixo])
ixref = ix;
}
} while (grpsiz != ix - ixs);
/*
* Try to move back the possibly merged group of changes, to match
* the recorded postion in the other file.
*/
while (ixref < ix) {
rchg[--ixs] = 1;
rchg[--ix] = 0;
while (rchgo[--ixo]);
}
}
return 0;
}
int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
xdchange_t *cscr = NULL, *xch;
char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
long i1, i2, l1, l2;
/*
* Trivial. Collects "groups" of changes and creates an edit script.
*/
for (i1 = xe->xdf1.nrec, i2 = xe->xdf2.nrec; i1 >= 0 || i2 >= 0; i1--, i2--)
if (rchg1[i1 - 1] || rchg2[i2 - 1]) {
for (l1 = i1; rchg1[i1 - 1]; i1--);
for (l2 = i2; rchg2[i2 - 1]; i2--);
if (!(xch = xdl_add_change(cscr, i1, i2, l1 - i1, l2 - i2))) {
xdl_free_script(cscr);
return -1;
}
cscr = xch;
}
*xscr = cscr;
return 0;
}
void xdl_free_script(xdchange_t *xscr) {
xdchange_t *xch;
while ((xch = xscr) != NULL) {
xscr = xscr->next;
xdl_free(xch);
}
}
int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdemitconf_t const *xecfg, xdemitcb_t *ecb) {
xdchange_t *xscr;
xdfenv_t xe;
if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) {
return -1;
}
if (xdl_change_compact(&xe.xdf1, &xe.xdf2) < 0 ||
xdl_change_compact(&xe.xdf2, &xe.xdf1) < 0 ||
xdl_build_script(&xe, &xscr) < 0) {
xdl_free_env(&xe);
return -1;
}
if (xscr) {
if (xdl_emit_diff(&xe, xscr, ecb, xecfg) < 0) {
xdl_free_script(xscr);
xdl_free_env(&xe);
return -1;
}
xdl_free_script(xscr);
}
xdl_free_env(&xe);
return 0;
}

View File

@ -0,0 +1,60 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XDIFFI_H)
#define XDIFFI_H
typedef struct s_diffdata {
long nrec;
unsigned long const *ha;
long *rindex;
char *rchg;
} diffdata_t;
typedef struct s_xdalgoenv {
long mxcost;
long snake_cnt;
long heur_min;
} xdalgoenv_t;
typedef struct s_xdchange {
struct s_xdchange *next;
long i1, i2;
long chg1, chg2;
} xdchange_t;
int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
diffdata_t *dd2, long off2, long lim2,
long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv);
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *xe);
int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
void xdl_free_script(xdchange_t *xscr);
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg);
#endif /* #if !defined(XDIFFI_H) */

132
src/libxdiff/xdiff/xemit.c Normal file
View File

@ -0,0 +1,132 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
*rec = xdf->recs[ri]->ptr;
return xdf->recs[ri]->size;
}
static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
long size, psize = strlen(pre);
char const *rec;
size = xdl_get_rec(xdf, ri, &rec);
if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
return -1;
}
return 0;
}
/*
* Starting at the passed change atom, find the latest change atom to be included
* inside the differential hunk according to the specified configuration.
*/
static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) {
xdchange_t *xch, *xchp;
for (xchp = xscr, xch = xscr->next; xch; xchp = xch, xch = xch->next)
if (xch->i1 - (xchp->i1 + xchp->chg1) > 2 * xecfg->ctxlen)
break;
return xchp;
}
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg) {
long s1, s2, e1, e2, lctx;
xdchange_t *xch, *xche;
for (xch = xche = xscr; xch; xch = xche->next) {
xche = xdl_get_hunk(xch, xecfg);
s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
lctx = xecfg->ctxlen;
lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
e1 = xche->i1 + xche->chg1 + lctx;
e2 = xche->i2 + xche->chg2 + lctx;
/*
* Emit current hunk header.
*/
if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, ecb) < 0)
return -1;
/*
* Emit pre-context.
*/
for (; s1 < xch->i1; s1++)
if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
return -1;
for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
/*
* Merge previous with current change atom.
*/
for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
return -1;
/*
* Removes lines from the first file.
*/
for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
return -1;
/*
* Adds lines from the second file.
*/
for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
return -1;
if (xch == xche)
break;
s1 = xch->i1 + xch->chg1;
s2 = xch->i2 + xch->chg2;
}
/*
* Emit post-context.
*/
for (s1 = xche->i1 + xche->chg1; s1 < e1; s1++)
if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
return -1;
}
return 0;
}

View File

@ -0,0 +1,34 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XEMIT_H)
#define XEMIT_H
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg);
#endif /* #if !defined(XEMIT_H) */

View File

@ -0,0 +1,71 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XINCLUDE_H)
#define XINCLUDE_H
#if defined(HAVE_WINCONFIG_H)
#include "winconfig.h"
#endif /* #if defined(HAVE_CONFIG_H) */
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif /* #if defined(HAVE_CONFIG_H) */
#if defined(HAVE_STDIO_H)
#include <stdio.h>
#endif /* #if defined(HAVE_STDIO_H) */
#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif /* #if defined(HAVE_STDLIB_H) */
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif /* #if defined(HAVE_UNISTD_H) */
#if defined(HAVE_STRING_H)
#include <string.h>
#endif /* #if defined(HAVE_STRING_H) */
#if defined(HAVE_LIMITS_H)
#include <limits.h>
#endif /* #if defined(HAVE_LIMITS_H) */
#include "xmacros.h"
#include "xmissing.h"
#include "xdiff.h"
#include "xtypes.h"
#include "xutils.h"
#include "xadler32.h"
#include "xprepare.h"
#include "xdiffi.h"
#include "xemit.h"
#include "xbdiff.h"
#endif /* #if !defined(XINCLUDE_H) */

View File

@ -0,0 +1,51 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XMACROS_H)
#define XMACROS_H
#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
#define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
#define XDL_ADDBITS(v, b) ((v) + ((v) >> (b)))
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
#define XDL_HASHLONG(v, b) (XDL_ADDBITS((unsigned long) (v), b) & XDL_MASKBITS(b))
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
#define XDL_RECMATCH(r1, r2) ((r1)->size == (r2)->size && memcmp((r1)->ptr, (r2)->ptr, (r1)->size) == 0)
#define XDL_LE32_PUT(p, v) do { \
unsigned char *__p = (unsigned char *) (p); \
*__p++ = (unsigned char) (v); \
*__p++ = (unsigned char) ((v) >> 8); \
*__p++ = (unsigned char) ((v) >> 16); \
*__p = (unsigned char) ((v) >> 24); \
} while (0)
#define XDL_LE32_GET(p, v) do { \
unsigned char const *__p = (unsigned char const *) (p); \
(v) = (unsigned long) __p[0] | ((unsigned long) __p[1]) << 8 | \
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
} while (0)
#endif /* #if !defined(XMACROS_H) */

View File

@ -0,0 +1,66 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_MERGE3_BLKSIZE (1024 * 8)
#define XDL_MERGE3_CTXLEN 3
int xdl_merge3(mmfile_t *mmfo, mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb,
xdemitcb_t *rjecb) {
xpparam_t xpp;
xdemitconf_t xecfg;
xdemitcb_t xecb;
mmfile_t mmfp;
if (xdl_init_mmfile(&mmfp, XDL_MERGE3_BLKSIZE, XDL_MMF_ATOMIC) < 0) {
return -1;
}
xpp.flags = 0;
xecfg.ctxlen = XDL_MERGE3_CTXLEN;
xecb.priv = &mmfp;
xecb.outf = xdl_mmfile_outf;
if (xdl_diff(mmfo, mmf2, &xpp, &xecfg, &xecb) < 0) {
xdl_free_mmfile(&mmfp);
return -1;
}
if (xdl_patch(mmf1, &mmfp, XDL_PATCH_NORMAL, ecb, rjecb) < 0) {
xdl_free_mmfile(&mmfp);
return -1;
}
xdl_free_mmfile(&mmfp);
return 0;
}

View File

@ -0,0 +1,92 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#if !defined(HAVE_MEMCHR)
void *memchr(void const *p, int c, long n) {
char const *pc = p;
for (; n; n--, pc++)
if (*pc == (char) c)
return pc;
return NULL;
}
#endif /* #if !defined(HAVE_MEMCHR) */
#if !defined(HAVE_MEMCMP)
int memcmp(void const *p1, void const *p2, long n) {
char const *pc1 = p1, *pc2 = p2;
for (; n; n--, pc1++, pc2++)
if (*pc1 != *pc2)
return *pc1 - *pc2;
return 0;
}
#endif /* #if !defined(HAVE_MEMCMP) */
#if !defined(HAVE_MEMCPY)
void *memcpy(void *d, void const *s, long n) {
char *dc = d;
char const *sc = s;
for (; n; n--, dc++, sc++)
*dc = *sc;
return d;
}
#endif /* #if !defined(HAVE_MEMCPY) */
#if !defined(HAVE_MEMSET)
void *memset(void *d, int c, long n) {
char *dc = d;
for (; n; n--, dc++)
*dc = (char) c;
return d;
}
#endif /* #if !defined(HAVE_MEMSET) */
#if !defined(HAVE_STRLEN)
long strlen(char const *s) {
char const *tmp;
for (tmp = s; *s; s++);
return (long) (s - tmp);
}
#endif /* #if !defined(HAVE_STRLEN) */

View File

@ -0,0 +1,56 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XMISSING_H)
#define XMISSING_H
#if !defined(CHAR_BIT)
#define CHAR_BIT 8
#endif /* #if !defined(CHAR_BIT) */
#if !defined(HAVE_MEMCHR)
void *memchr(void const *p, int c, long n);
#endif /* #if !defined(HAVE_MEMCHR) */
#if !defined(HAVE_MEMCMP)
int memcmp(void const *p1, void const *p2, long n);
#endif /* #if !defined(HAVE_MEMCMP) */
#if !defined(HAVE_MEMCPY)
void *memcpy(void *d, void const *s, long n);
#endif /* #if !defined(HAVE_MEMCPY) */
#if !defined(HAVE_MEMSET)
void *memset(void *d, int c, long n);
#endif /* #if !defined(HAVE_MEMSET) */
#if !defined(HAVE_STRLEN)
long strlen(char const *s);
#endif /* #if !defined(HAVE_STRLEN) */
#endif /* #if !defined(XMISSING_H) */

View File

@ -0,0 +1,641 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_MAX_FUZZ 3
#define XDL_MIN_SYNCLINES 4
typedef struct s_recinfo {
char const *ptr;
long size;
} recinfo_t;
typedef struct s_recfile {
mmfile_t *mf;
long nrec;
recinfo_t *recs;
} recfile_t;
typedef struct s_hunkinfo {
long s1, s2;
long c1, c2;
long cmn, radd, rdel, pctx, sctx;
} hunkinfo_t;
typedef struct s_patchstats {
long adds, dels;
} patchstats_t;
typedef struct s_patch {
recfile_t rf;
hunkinfo_t hi;
long hkrec;
long hklen;
long flags;
patchstats_t ps;
int fuzzies;
} patch_t;
static int xdl_load_hunk_info(char const *line, long size, hunkinfo_t *hki);
static int xdl_init_recfile(mmfile_t *mf, int ispatch, recfile_t *rf);
static void xdl_free_recfile(recfile_t *rf);
static char const *xdl_recfile_get(recfile_t *rf, long irec, long *size);
static int xdl_init_patch(mmfile_t *mf, long flags, patch_t *pch);
static void xdl_free_patch(patch_t *pch);
static int xdl_load_hunk(patch_t *pch, long hkrec);
static int xdl_first_hunk(patch_t *pch);
static int xdl_next_hunk(patch_t *pch);
static int xdl_line_match(patch_t *pch, const char *s, long ns, char const *m, long nm);
static int xdl_hunk_match(recfile_t *rf, long irec, patch_t *pch, int mode, int fuzz);
static int xdl_find_hunk(recfile_t *rf, long ibase, patch_t *pch, int mode,
int fuzz, long *hkpos, int *exact);
static int xdl_emit_rfile_line(recfile_t *rf, long line, xdemitcb_t *ecb);
static int xdl_flush_section(recfile_t *rf, long start, long top, xdemitcb_t *ecb);
static int xdl_apply_hunk(recfile_t *rf, long hkpos, patch_t *pch, int mode,
long *ibase, xdemitcb_t *ecb);
static int xdl_reject_hunk(recfile_t *rf, patch_t *pch, int mode,
xdemitcb_t *rjecb);
static int xdl_process_hunk(recfile_t *rff, patch_t *pch, long *ibase, int mode,
xdemitcb_t *ecb, xdemitcb_t *rjecb);
static int xdl_load_hunk_info(char const *line, long size, hunkinfo_t *hki) {
char const *next;
/*
* The diff header format should be:
*
* @@ -OP,OC +NP,NC @@
*
* Unfortunately some software avoid to emit OP or/and NP in case
* of not existing old or new file (it should be mitted as zero).
* We need to handle both syntaxes.
*/
if (memcmp(line, "@@ -", 4))
return -1;
line += 4;
size -= 4;
if (!size || !XDL_ISDIGIT(*line))
return -1;
hki->s1 = xdl_atol(line, &next);
size -= next - line;
line = next;
if (!size)
return -1;
if (*line == ',') {
size--, line++;
if (!size || !XDL_ISDIGIT(*line))
return -1;
hki->c1 = xdl_atol(line, &next);
size -= next - line;
line = next;
if (!size || *line != ' ')
return -1;
size--, line++;
} else if (*line == ' ') {
size--, line++;
hki->c1 = hki->s1;
hki->s1 = 0;
} else
return -1;
if (!size || *line != '+')
return -1;
size--, line++;
if (!size || !XDL_ISDIGIT(*line))
return -1;
hki->s2 = xdl_atol(line, &next);
size -= next - line;
line = next;
if (!size)
return -1;
if (*line == ',') {
size--, line++;
if (!size || !XDL_ISDIGIT(*line))
return -1;
hki->c2 = xdl_atol(line, &next);
size -= next - line;
line = next;
if (!size || *line != ' ')
return -1;
size--, line++;
} else if (*line == ' ') {
size--, line++;
hki->c2 = hki->s2;
hki->s2 = 0;
} else
return -1;
if (size < 2 || memcmp(line, "@@", 2) != 0)
return -1;
/*
* We start from zero, so decrement by one unless it's the special position
* '0' inside the unified diff (new or deleted file).
*/
if (hki->s1 > 0 && hki->c1 > 0)
hki->s1--;
if (hki->s2 > 0 && hki->c2 > 0)
hki->s2--;
return 0;
}
static int xdl_init_recfile(mmfile_t *mf, int ispatch, recfile_t *rf) {
long narec, nrec, bsize;
recinfo_t *recs, *rrecs;
char const *blk, *cur, *top, *eol;
narec = xdl_guess_lines(mf);
if (!(recs = (recinfo_t *) xdl_malloc(narec * sizeof(recinfo_t)))) {
return -1;
}
nrec = 0;
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
for (top = blk + bsize;;) {
if (cur >= top) {
if (!(cur = blk = xdl_mmfile_next(mf, &bsize)))
break;
top = blk + bsize;
}
if (nrec >= narec) {
narec *= 2;
if (!(rrecs = (recinfo_t *)
xdl_realloc(recs, narec * sizeof(recinfo_t)))) {
xdl_free(recs);
return -1;
}
recs = rrecs;
}
recs[nrec].ptr = cur;
if (!(eol = memchr(cur, '\n', top - cur)))
eol = top - 1;
recs[nrec].size = (long) (eol - cur) + 1;
if (ispatch && *cur == '\\' && nrec > 0 && recs[nrec - 1].size > 0 &&
recs[nrec - 1].ptr[recs[nrec - 1].size - 1] == '\n')
recs[nrec - 1].size--;
else
nrec++;
cur = eol + 1;
}
}
rf->mf = mf;
rf->nrec = nrec;
rf->recs = recs;
return 0;
}
static void xdl_free_recfile(recfile_t *rf) {
xdl_free(rf->recs);
}
static char const *xdl_recfile_get(recfile_t *rf, long irec, long *size) {
if (irec < 0 || irec >= rf->nrec)
return NULL;
*size = rf->recs[irec].size;
return rf->recs[irec].ptr;
}
static int xdl_init_patch(mmfile_t *mf, long flags, patch_t *pch) {
if (xdl_init_recfile(mf, 1, &pch->rf) < 0) {
return -1;
}
pch->hkrec = 0;
pch->hklen = 0;
pch->flags = flags;
pch->ps.adds = pch->ps.dels = 0;
pch->fuzzies = 0;
return 0;
}
static void xdl_free_patch(patch_t *pch) {
xdl_free_recfile(&pch->rf);
}
static int xdl_load_hunk(patch_t *pch, long hkrec) {
long size, i, nb;
char const *line;
for (;; hkrec++) {
pch->hkrec = hkrec;
if (!(line = xdl_recfile_get(&pch->rf, pch->hkrec, &size)))
return 0;
if (*line == '@')
break;
}
if (xdl_load_hunk_info(line, size, &pch->hi) < 0) {
return -1;
}
pch->hi.cmn = pch->hi.radd = pch->hi.rdel = pch->hi.pctx = pch->hi.sctx = 0;
for (i = pch->hkrec + 1, nb = 0;
(line = xdl_recfile_get(&pch->rf, i, &size)) != NULL; i++) {
if (*line == '@' || *line == '\n')
break;
if (*line == ' ') {
nb++;
pch->hi.cmn++;
} else if (*line == '+') {
if (pch->hi.radd + pch->hi.rdel == 0)
pch->hi.pctx = nb;
nb = 0;
pch->hi.radd++;
} else if (*line == '-') {
if (pch->hi.radd + pch->hi.rdel == 0)
pch->hi.pctx = nb;
nb = 0;
pch->hi.rdel++;
} else {
return -1;
}
}
pch->hi.sctx = nb;
if (pch->hi.cmn + pch->hi.radd != pch->hi.c2 ||
pch->hi.cmn + pch->hi.rdel != pch->hi.c1) {
return -1;
}
pch->hklen = i - pch->hkrec - 1;
return 1;
}
static int xdl_first_hunk(patch_t *pch) {
return xdl_load_hunk(pch, 0);
}
static int xdl_next_hunk(patch_t *pch) {
return xdl_load_hunk(pch, pch->hkrec + pch->hklen + 1);
}
static int xdl_line_match(patch_t *pch, const char *s, long ns, char const *m, long nm) {
for (; ns > 0 && (s[ns - 1] == '\r' || s[ns - 1] == '\n'); ns--);
for (; nm > 0 && (m[nm - 1] == '\r' || m[nm - 1] == '\n'); nm--);
if (pch->flags & XDL_PATCH_IGNOREBSPACE) {
for (; ns > 0 && (*s == ' ' || *s == '\t'); ns--, s++);
for (; ns > 0 && (s[ns - 1] == ' ' || s[ns - 1] == '\t'); ns--);
for (; nm > 0 && (*m == ' ' || *m == '\t'); nm--, m++);
for (; nm > 0 && (m[nm - 1] == ' ' || m[nm - 1] == '\t'); nm--);
}
return ns == nm && memcmp(s, m, ns) == 0;
}
static int xdl_hunk_match(recfile_t *rf, long irec, patch_t *pch, int mode, int fuzz) {
long i, j, z, fsize, psize, ptop, pfuzz, sfuzz, misses;
char const *fline, *pline;
/*
* Limit fuzz to not be greater than the prefix and suffix context.
*/
pfuzz = fuzz < pch->hi.pctx ? fuzz: pch->hi.pctx;
sfuzz = fuzz < pch->hi.sctx ? fuzz: pch->hi.sctx;
/*
* First loop through the prefix fuzz area. In this loop we simply
* note mismatching lines. We allow missing lines here, that is,
* some prefix context lines are missing.
*/
for (z = pfuzz, misses = 0, i = irec, j = pch->hkrec + 1,
ptop = pch->hkrec + 1 + pch->hklen - sfuzz;
z > 0 && i < rf->nrec && j < ptop; i++, j++, z--) {
if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)))
return 0;
if (!(fline = xdl_recfile_get(rf, i, &fsize)) ||
!xdl_line_match(pch, fline, fsize, pline + 1, psize - 1))
misses++;
}
if (misses > fuzz)
return 0;
/*
* Strict match loop.
*/
for (; i < rf->nrec && j < ptop; i++, j++) {
for (; j < ptop; j++) {
if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)))
return 0;
if (*pline == ' ' || *pline == mode)
break;
}
if (j == ptop)
break;
if (!(fline = xdl_recfile_get(rf, i, &fsize)) ||
!xdl_line_match(pch, fline, fsize, pline + 1, psize - 1))
return 0;
}
for (; j < ptop; j++)
if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)) ||
*pline == ' ' || *pline == mode)
return 0;
/*
* Finally loop through the suffix fuzz area. In this loop we simply
* note mismatching lines. We allow missing lines here, that is,
* some suffix context lines are missing.
*/
for (z = sfuzz; z > 0 && i < rf->nrec; i++, j++, z--) {
if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)))
return 0;
if (!(fline = xdl_recfile_get(rf, i, &fsize)) ||
!xdl_line_match(pch, fline, fsize, pline + 1, psize - 1))
misses++;
}
return misses <= fuzz;
}
static int xdl_find_hunk(recfile_t *rf, long ibase, patch_t *pch, int mode,
int fuzz, long *hkpos, int *exact) {
long hpos, hlen, i, j;
long pos[2];
hpos = mode == '-' ? pch->hi.s1: pch->hi.s2;
hlen = mode == '-' ? pch->hi.cmn + pch->hi.rdel: pch->hi.cmn + pch->hi.radd;
if (xdl_hunk_match(rf, hpos, pch, mode, fuzz)) {
*hkpos = hpos;
*exact = 1;
return 1;
}
for (i = 1;; i++) {
/*
* We allow a negative starting hunk position, up to the
* number of prefix context lines.
*/
j = 0;
if (hpos - i >= ibase - pch->hi.pctx)
pos[j++] = hpos - i;
if (hpos + i + hlen <= rf->nrec)
pos[j++] = hpos + i;
if (!j)
break;
for (j--; j >= 0; j--)
if (xdl_hunk_match(rf, pos[j], pch, mode, fuzz)) {
*hkpos = pos[j];
*exact = 0;
return 1;
}
}
return 0;
}
static int xdl_emit_rfile_line(recfile_t *rf, long line, xdemitcb_t *ecb) {
mmbuffer_t mb;
if (!(mb.ptr = (char *) xdl_recfile_get(rf, line, &mb.size)) ||
ecb->outf(ecb->priv, &mb, 1) < 0) {
return -1;
}
return 0;
}
static int xdl_flush_section(recfile_t *rf, long start, long top, xdemitcb_t *ecb) {
long i;
for (i = start; i <= top; i++) {
if (xdl_emit_rfile_line(rf, i, ecb) < 0) {
return -1;
}
}
return 0;
}
static int xdl_apply_hunk(recfile_t *rf, long hkpos, patch_t *pch, int mode,
long *ibase, xdemitcb_t *ecb) {
long j, psize, ptop;
char const *pline;
mmbuffer_t mb;
/*
* The hunk starting position (hkpos) can be negative, up to the number
* of prefix context lines. Since this function only emit the core of
* the hunk (the remaining lines are flushed by xdl_flush_section() calls)
* we need to normalize it by adding the number of prefix context lines.
* The normalized value of the starting position is then greater/equal
* to zero.
*/
hkpos += pch->hi.pctx;
if (xdl_flush_section(rf, *ibase, hkpos - 1, ecb) < 0) {
return -1;
}
*ibase = hkpos;
for (j = pch->hkrec + 1 + pch->hi.pctx,
ptop = pch->hkrec + 1 + pch->hklen - pch->hi.sctx; j < ptop; j++) {
if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) {
return -1;
}
if (*pline == ' ') {
if (xdl_emit_rfile_line(rf, *ibase, ecb) < 0) {
return -1;
}
(*ibase)++;
} else if (*pline != mode) {
mb.ptr = (char *) pline + 1;
mb.size = psize - 1;
if (ecb->outf(ecb->priv, &mb, 1) < 0) {
return -1;
}
pch->ps.adds++;
} else {
(*ibase)++;
pch->ps.dels++;
}
}
return 0;
}
static int xdl_reject_hunk(recfile_t *rf, patch_t *pch, int mode,
xdemitcb_t *rjecb) {
long i, size, s1, s2, c1, c2;
char const *line, *pre;
mmbuffer_t mb;
if (mode == '-') {
s1 = pch->hi.s1;
s2 = pch->hi.s2;
c1 = pch->hi.c1;
c2 = pch->hi.c2;
} else {
s1 = pch->hi.s2;
s2 = pch->hi.s1;
c1 = pch->hi.c2;
c2 = pch->hi.c1;
}
s1 += pch->ps.adds - pch->ps.dels;
if (xdl_emit_hunk_hdr(s1 + 1, c1, s2 + 1, c2, rjecb) < 0) {
return -1;
}
for (i = pch->hkrec + 1;
(line = xdl_recfile_get(&pch->rf, i, &size)) != NULL; i++) {
if (*line == '@' || *line == '\n')
break;
if (mode == '-' || *line == ' ') {
mb.ptr = (char *) line;
mb.size = size;
if (rjecb->outf(rjecb->priv, &mb, 1) < 0) {
return -1;
}
} else {
pre = *line == '+' ? "-": "+";
if (xdl_emit_diffrec(line + 1, size - 1, pre, strlen(pre),
rjecb) < 0) {
return -1;
}
}
}
return 0;
}
static int xdl_process_hunk(recfile_t *rff, patch_t *pch, long *ibase, int mode,
xdemitcb_t *ecb, xdemitcb_t *rjecb) {
int fuzz, exact, hlen, maxfuzz;
long hkpos;
hlen = mode == '-' ? pch->hi.cmn + pch->hi.rdel: pch->hi.cmn + pch->hi.radd;
maxfuzz = XDL_MAX_FUZZ;
if (hlen - maxfuzz < XDL_MIN_SYNCLINES)
maxfuzz = hlen - XDL_MIN_SYNCLINES;
if (maxfuzz < 0)
maxfuzz = 0;
for (fuzz = 0; fuzz <= maxfuzz; fuzz++) {
if (xdl_find_hunk(rff, *ibase, pch, mode, fuzz,
&hkpos, &exact)) {
if (xdl_apply_hunk(rff, hkpos, pch, mode,
ibase, ecb) < 0) {
return -1;
}
if (!exact || fuzz)
pch->fuzzies++;
return 0;
}
}
if (xdl_reject_hunk(rff, pch, mode, rjecb) < 0) {
return -1;
}
return 0;
}
int xdl_patch(mmfile_t *mf, mmfile_t *mfp, int mode, xdemitcb_t *ecb,
xdemitcb_t *rjecb) {
int hkres, exact;
long hkpos, ibase;
recfile_t rff;
patch_t pch;
if (xdl_init_recfile(mf, 0, &rff) < 0) {
return -1;
}
if (xdl_init_patch(mfp, mode & ~XDL_PATCH_MODEMASK, &pch) < 0) {
xdl_free_recfile(&rff);
return -1;
}
mode &= XDL_PATCH_MODEMASK;
ibase = 0;
if ((hkres = xdl_first_hunk(&pch)) > 0) {
do {
if (xdl_process_hunk(&rff, &pch, &ibase, mode,
ecb, rjecb) < 0) {
xdl_free_patch(&pch);
xdl_free_recfile(&rff);
return -1;
}
} while ((hkres = xdl_next_hunk(&pch)) > 0);
}
if (hkres < 0) {
xdl_free_patch(&pch);
xdl_free_recfile(&rff);
return -1;
}
if (xdl_flush_section(&rff, ibase, rff.nrec - 1, ecb) < 0) {
xdl_free_patch(&pch);
xdl_free_recfile(&rff);
return -1;
}
xdl_free_patch(&pch);
xdl_free_recfile(&rff);
return pch.fuzzies;
}

View File

@ -0,0 +1,456 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_KPDIS_RUN 4
#define XDL_MAX_EQLIMIT 1024
#define XDL_SIMSCAN_WINDOWN 100
typedef struct s_xdlclass {
struct s_xdlclass *next;
unsigned long ha;
char const *line;
long size;
long idx;
} xdlclass_t;
typedef struct s_xdlclassifier {
unsigned int hbits;
long hsize;
xdlclass_t **rchash;
chastore_t ncha;
long count;
} xdlclassifier_t;
static int xdl_init_classifier(xdlclassifier_t *cf, long size) {
long i;
cf->hbits = xdl_hashbits((unsigned int) size);
cf->hsize = 1 << cf->hbits;
if (xdl_cha_init(&cf->ncha, sizeof(xdlclass_t), size / 4 + 1) < 0) {
return -1;
}
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
xdl_cha_free(&cf->ncha);
return -1;
}
for (i = 0; i < cf->hsize; i++)
cf->rchash[i] = NULL;
cf->count = 0;
return 0;
}
static void xdl_free_classifier(xdlclassifier_t *cf) {
xdl_free(cf->rchash);
xdl_cha_free(&cf->ncha);
}
static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned int hbits,
xrecord_t *rec) {
long hi;
char const *line;
xdlclass_t *rcrec;
line = rec->ptr;
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
if (rcrec->ha == rec->ha && rcrec->size == rec->size &&
!memcmp(line, rcrec->line, rec->size))
break;
if (!rcrec) {
if (!(rcrec = xdl_cha_alloc(&cf->ncha))) {
return -1;
}
rcrec->idx = cf->count++;
rcrec->line = line;
rcrec->size = rec->size;
rcrec->ha = rec->ha;
rcrec->next = cf->rchash[hi];
cf->rchash[hi] = rcrec;
}
rec->ha = (unsigned long) rcrec->idx;
hi = (long) XDL_HASHLONG(rec->ha, hbits);
rec->next = rhash[hi];
rhash[hi] = rec;
return 0;
}
static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,
xdlclassifier_t *cf, xdfile_t *xdf) {
unsigned int hbits;
long i, nrec, hsize, bsize;
unsigned long hav;
char const *blk, *cur, *top, *prev;
xrecord_t *crec;
xrecord_t **recs, **rrecs;
xrecord_t **rhash;
unsigned long *ha;
char *rchg;
long *rindex;
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) {
return -1;
}
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) {
xdl_cha_free(&xdf->rcha);
return -1;
}
hbits = xdl_hashbits((unsigned int) narec);
hsize = 1 << hbits;
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) {
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
for (i = 0; i < hsize; i++)
rhash[i] = NULL;
nrec = 0;
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
for (top = blk + bsize;;) {
if (cur >= top) {
if (!(cur = blk = xdl_mmfile_next(mf, &bsize)))
break;
top = blk + bsize;
}
prev = cur;
hav = xdl_hash_record(&cur, top);
if (nrec >= narec) {
narec *= 2;
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
recs = rrecs;
}
if (!(crec = xdl_cha_alloc(&xdf->rcha))) {
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
crec->ptr = prev;
crec->size = (long) (cur - prev);
crec->ha = hav;
recs[nrec++] = crec;
if (xdl_classify_record(cf, rhash, hbits, crec) < 0) {
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
}
}
if (!(rchg = (char *) xdl_malloc(nrec + 2))) {
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
memset(rchg, 0, nrec + 2);
if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {
xdl_free(rchg);
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) {
xdl_free(rindex);
xdl_free(rchg);
xdl_free(rhash);
xdl_free(recs);
xdl_cha_free(&xdf->rcha);
return -1;
}
xdf->nrec = nrec;
xdf->recs = recs;
xdf->hbits = hbits;
xdf->rhash = rhash;
xdf->rchg = rchg + 1;
xdf->rindex = rindex;
xdf->nreff = 0;
xdf->ha = ha;
xdf->dstart = 0;
xdf->dend = nrec - 1;
return 0;
}
static void xdl_free_ctx(xdfile_t *xdf) {
xdl_free(xdf->rhash);
xdl_free(xdf->rindex);
xdl_free(xdf->rchg - 1);
xdl_free(xdf->ha);
xdl_free(xdf->recs);
xdl_cha_free(&xdf->rcha);
}
static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
long r, rdis0, rpdis0, rdis1, rpdis1;
/*
* Limits the window the is examined during the similar-lines
* scan. The loops below stops when dis[i - r] == 1 (line that
* has no match), but there are corner cases where the loop
* proceed all the way to the extremities by causing huge
* performance penalties in case of big files.
*/
if (i - s > XDL_SIMSCAN_WINDOWN)
s = i - XDL_SIMSCAN_WINDOWN;
if (e - i > XDL_SIMSCAN_WINDOWN)
e = i + XDL_SIMSCAN_WINDOWN;
/*
* Scans the lines before 'i' to find a run of lines that either
* have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).
* Note that we always call this function with dis[i] > 1, so the
* current line (i) is already a multimatch line.
*/
for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) {
if (!dis[i - r])
rdis0++;
else if (dis[i - r] == 2)
rpdis0++;
else
break;
}
/*
* If the run before the line 'i' found only multimatch lines, we
* return 0 and hence we don't make the current line (i) discarded.
* We want to discard multimatch lines only when they appear in the
* middle of runs with nomatch lines (dis[j] == 0).
*/
if (rdis0 == 0)
return 0;
for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) {
if (!dis[i + r])
rdis1++;
else if (dis[i + r] == 2)
rpdis1++;
else
break;
}
/*
* If the run after the line 'i' found only multimatch lines, we
* return 0 and hence we don't make the current line (i) discarded.
*/
if (rdis1 == 0)
return 0;
rdis1 += rdis0;
rpdis1 += rpdis0;
return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1);
}
/*
* Try to reduce the problem complexity, discard records that have no
* matches on the other file. Also, lines that have multiple matches
* might be potentially discarded if they happear in a run of discardable.
*/
static int xdl_cleanup_records(xdfile_t *xdf1, xdfile_t *xdf2) {
long i, nm, rhi, nreff, mlim;
unsigned long hav;
xrecord_t **recs;
xrecord_t *rec;
char *dis, *dis1, *dis2;
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
return -1;
}
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
dis1 = dis;
dis2 = dis1 + xdf1->nrec + 1;
if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT)
mlim = XDL_MAX_EQLIMIT;
for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) {
hav = (*recs)->ha;
rhi = (long) XDL_HASHLONG(hav, xdf2->hbits);
for (nm = 0, rec = xdf2->rhash[rhi]; rec; rec = rec->next)
if (rec->ha == hav && ++nm == mlim)
break;
dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
}
if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT)
mlim = XDL_MAX_EQLIMIT;
for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) {
hav = (*recs)->ha;
rhi = (long) XDL_HASHLONG(hav, xdf1->hbits);
for (nm = 0, rec = xdf1->rhash[rhi]; rec; rec = rec->next)
if (rec->ha == hav && ++nm == mlim)
break;
dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
}
for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart];
i <= xdf1->dend; i++, recs++) {
if (dis1[i] == 1 ||
(dis1[i] == 2 && !xdl_clean_mmatch(dis1, i, xdf1->dstart, xdf1->dend))) {
xdf1->rindex[nreff] = i;
xdf1->ha[nreff] = (*recs)->ha;
nreff++;
} else
xdf1->rchg[i] = 1;
}
xdf1->nreff = nreff;
for (nreff = 0, i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart];
i <= xdf2->dend; i++, recs++) {
if (dis2[i] == 1 ||
(dis2[i] == 2 && !xdl_clean_mmatch(dis2, i, xdf2->dstart, xdf2->dend))) {
xdf2->rindex[nreff] = i;
xdf2->ha[nreff] = (*recs)->ha;
nreff++;
} else
xdf2->rchg[i] = 1;
}
xdf2->nreff = nreff;
xdl_free(dis);
return 0;
}
/*
* Early trim initial and terminal matching records.
*/
static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) {
long i, lim;
xrecord_t **recs1, **recs2;
recs1 = xdf1->recs;
recs2 = xdf2->recs;
for (i = 0, lim = XDL_MIN(xdf1->nrec, xdf2->nrec); i < lim;
i++, recs1++, recs2++)
if ((*recs1)->ha != (*recs2)->ha)
break;
xdf1->dstart = xdf2->dstart = i;
recs1 = xdf1->recs + xdf1->nrec - 1;
recs2 = xdf2->recs + xdf2->nrec - 1;
for (lim -= i, i = 0; i < lim; i++, recs1--, recs2--)
if ((*recs1)->ha != (*recs2)->ha)
break;
xdf1->dend = xdf1->nrec - i - 1;
xdf2->dend = xdf2->nrec - i - 1;
return 0;
}
static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2) {
if (xdl_trim_ends(xdf1, xdf2) < 0 ||
xdl_cleanup_records(xdf1, xdf2) < 0) {
return -1;
}
return 0;
}
int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *xe) {
long enl1, enl2;
xdlclassifier_t cf;
enl1 = xdl_guess_lines(mf1) + 1;
enl2 = xdl_guess_lines(mf2) + 1;
if (xdl_init_classifier(&cf, enl1 + enl2 + 1) < 0) {
return -1;
}
if (xdl_prepare_ctx(mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
xdl_free_classifier(&cf);
return -1;
}
if (xdl_prepare_ctx(mf2, enl2, xpp, &cf, &xe->xdf2) < 0) {
xdl_free_ctx(&xe->xdf1);
xdl_free_classifier(&cf);
return -1;
}
xdl_free_classifier(&cf);
if (xdl_optimize_ctxs(&xe->xdf1, &xe->xdf2) < 0) {
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);
return -1;
}
return 0;
}
void xdl_free_env(xdfenv_t *xe) {
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);
}

View File

@ -0,0 +1,35 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XPREPARE_H)
#define XPREPARE_H
int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *xe);
void xdl_free_env(xdfenv_t *xe);
#endif /* #if !defined(XPREPARE_H) */

View File

@ -0,0 +1,381 @@
/*
* xrabdiff by Davide Libenzi (Rabin's polynomial fingerprint based delta generator)
* Copyright (C) 2006 Davide Libenzi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*
* Hints, ideas and code for the implementation came from:
*
* Rabin's original paper: http://www.xmailserver.org/rabin.pdf
* Chan & Lu's paper: http://www.xmailserver.org/rabin_impl.pdf
* Broder's paper: http://www.xmailserver.org/rabin_apps.pdf
* LBFS source code: http://www.fs.net/sfswww/lbfs/
* Geert Bosch's post: http://marc.theaimsgroup.com/?l=git&m=114565424620771&w=2
*
*/
#include "xinclude.h"
#if !defined(XRABPLY_TYPE32) && !defined(XRABPLY_TYPE64)
#define XRABPLY_TYPE64 long long
#define XV64(v) ((xply_word) v ## ULL)
#endif
#include "xrabply.c"
#define XRAB_SLIDE(v, c) do { \
if (++wpos == XRAB_WNDSIZE) wpos = 0; \
v ^= U[wbuf[wpos]]; \
wbuf[wpos] = (c); \
v = ((v << 8) | (c)) ^ T[v >> XRAB_SHIFT]; \
} while (0)
#define XRAB_MINCPYSIZE 12
#define XRAB_WBITS (sizeof(xply_word) * 8)
typedef struct s_xrabctx {
long idxsize;
long *idx;
unsigned char const *data;
long size;
} xrabctx_t;
typedef struct s_xrabcpyi {
long src;
long tgt;
long len;
} xrabcpyi_t;
typedef struct s_xrabcpyi_arena {
long cnt, size;
xrabcpyi_t *acpy;
} xrabcpyi_arena_t;
static void xrab_init_cpyarena(xrabcpyi_arena_t *aca) {
aca->cnt = aca->size = 0;
aca->acpy = NULL;
}
static void xrab_free_cpyarena(xrabcpyi_arena_t *aca) {
xdl_free(aca->acpy);
}
static int xrab_add_cpy(xrabcpyi_arena_t *aca, xrabcpyi_t const *rcpy) {
long size;
xrabcpyi_t *acpy;
if (aca->cnt >= aca->size) {
size = 2 * aca->size + 1024;
if ((acpy = (xrabcpyi_t *)
xdl_realloc(aca->acpy, size * sizeof(xrabcpyi_t))) == NULL)
return -1;
aca->acpy = acpy;
aca->size = size;
}
aca->acpy[aca->cnt++] = *rcpy;
return 0;
}
static long xrab_cmnseq(unsigned char const *data, long start, long size) {
unsigned char ch = data[start];
unsigned char const *ptr, *top;
for (ptr = data + start + 1, top = data + size; ptr < top && ch == *ptr; ptr++);
return (long) (ptr - (data + start + 1));
}
static int xrab_build_ctx(unsigned char const *data, long size, xrabctx_t *ctx) {
long i, isize, idxsize, seq, wpos = 0;
xply_word fp = 0, mask;
unsigned char ch;
unsigned char const *ptr, *eot;
long *idx;
unsigned char wbuf[XRAB_WNDSIZE];
long maxoffs[256];
long maxseq[256];
xply_word maxfp[256];
memset(wbuf, 0, sizeof(wbuf));
memset(maxseq, 0, sizeof(maxseq));
isize = 2 * (size / XRAB_WNDSIZE);
for (idxsize = 1; idxsize < isize; idxsize <<= 1);
mask = (xply_word) (idxsize - 1);
if ((idx = (long *) xdl_malloc(idxsize * sizeof(long))) == NULL)
return -1;
memset(idx, 0, idxsize * sizeof(long));
for (i = 0; i + XRAB_WNDSIZE < size; i += XRAB_WNDSIZE) {
/*
* Generate a brand new hash for the current window. Here we could
* try to perform pseudo-loop unroll by 4 blocks if necessary, and
* if we force XRAB_WNDSIZE to be a multiple of 4, we could reduce
* the branch occurence inside XRAB_SLIDE by a factor of 4.
*/
for (ptr = data + i, eot = ptr + XRAB_WNDSIZE; ptr < eot; ptr++)
XRAB_SLIDE(fp, *ptr);
/*
* Try to scan for single value scans, and store them in the
* array according to the longest one. Before we do a fast check
* to avoid calling xrab_cmnseq() when not necessary.
*/
if ((ch = data[i]) == data[i + XRAB_WNDSIZE - 1] &&
(seq = xrab_cmnseq(data, i, size)) > XRAB_WNDSIZE &&
seq > maxseq[ch]) {
maxseq[ch] = seq;
maxfp[ch] = fp;
maxoffs[ch] = i + XRAB_WNDSIZE;
seq = (seq / XRAB_WNDSIZE) * XRAB_WNDSIZE;
i += seq - XRAB_WNDSIZE;
} else
idx[fp & mask] = i + XRAB_WNDSIZE;
}
/*
* Restore back the logest sequences by overwriting target hash buckets.
*/
for (i = 0; i < 256; i++)
if (maxseq[i])
idx[maxfp[i] & mask] = maxoffs[i];
ctx->idxsize = idxsize;
ctx->idx = idx;
ctx->data = data;
ctx->size = size;
return 0;
}
static void xrab_free_ctx(xrabctx_t *ctx) {
xdl_free(ctx->idx);
}
static int xrab_diff(unsigned char const *data, long size, xrabctx_t *ctx,
xrabcpyi_arena_t *aca) {
long i, offs, ssize, src, tgt, esrc, etgt, wpos = 0;
xply_word fp = 0, mask;
long const *idx;
unsigned char const *sdata;
xrabcpyi_t rcpy;
unsigned char wbuf[XRAB_WNDSIZE];
xrab_init_cpyarena(aca);
memset(wbuf, 0, sizeof(wbuf));
for (i = 0; i < XRAB_WNDSIZE - 1 && i < size; i++)
XRAB_SLIDE(fp, data[i]);
idx = ctx->idx;
sdata = ctx->data;
ssize = ctx->size;
mask = (xply_word) (ctx->idxsize - 1);
while (i < size) {
unsigned char ch = data[i++];
XRAB_SLIDE(fp, ch);
offs = idx[fp & mask];
/*
* Fast check here to probabilistically reduce false positives
* that would trigger the slow path below.
*/
if (offs == 0 || ch != sdata[offs - 1])
continue;
/*
* Stretch the match both sides as far as possible.
*/
src = offs - 1;
tgt = i - 1;
for (; tgt > 0 && src > 0 && data[tgt - 1] == sdata[src - 1];
tgt--, src--);
esrc = offs;
etgt = i;
for (; etgt < size && esrc < ssize && data[etgt] == sdata[esrc];
etgt++, esrc++);
/*
* Avoid considering copies smaller than the XRAB_MINCPYSIZE
* threshold.
*/
if (etgt - tgt >= XRAB_MINCPYSIZE) {
rcpy.src = src;
rcpy.tgt = tgt;
rcpy.len = etgt - tgt;
if (xrab_add_cpy(aca, &rcpy) < 0) {
xrab_free_cpyarena(aca);
return -1;
}
/*
* Fill up the new window and exit with 'i' properly set on exit.
*/
for (i = etgt - XRAB_WNDSIZE; i < etgt; i++)
XRAB_SLIDE(fp, data[i]);
}
}
return 0;
}
static int xrab_tune_cpyarena(unsigned char const *data, long size, xrabctx_t *ctx,
xrabcpyi_arena_t *aca) {
long i, cpos;
xrabcpyi_t *rcpy;
for (cpos = size, i = aca->cnt - 1; i >= 0; i--) {
rcpy = aca->acpy + i;
if (rcpy->tgt >= cpos)
rcpy->len = 0;
else if (rcpy->tgt + rcpy->len > cpos) {
if ((rcpy->len = cpos - rcpy->tgt) >= XRAB_MINCPYSIZE)
cpos = rcpy->tgt;
else
rcpy->len = 0;
} else
cpos = rcpy->tgt;
}
return 0;
}
int xdl_rabdiff_mb(mmbuffer_t *mmb1, mmbuffer_t *mmb2, xdemitcb_t *ecb) {
long i, cpos, size;
unsigned long fp;
xrabcpyi_t *rcpy;
xrabctx_t ctx;
xrabcpyi_arena_t aca;
mmbuffer_t mb[2];
unsigned char cpybuf[32];
fp = xdl_mmb_adler32(mmb1);
if (xrab_build_ctx((unsigned char const *) mmb1->ptr, mmb1->size,
&ctx) < 0)
return -1;
if (xrab_diff((unsigned char const *) mmb2->ptr, mmb2->size, &ctx,
&aca) < 0) {
xrab_free_ctx(&ctx);
return -1;
}
xrab_tune_cpyarena((unsigned char const *) mmb2->ptr, mmb2->size, &ctx,
&aca);
xrab_free_ctx(&ctx);
/*
* Prepare and emit the binary patch file header. It will be used
* to verify that that file being patched matches in size and fingerprint
* the one that generated the patch.
*/
size = mmb1->size;
XDL_LE32_PUT(cpybuf, fp);
XDL_LE32_PUT(cpybuf + 4, size);
mb[0].ptr = (char *) cpybuf;
mb[0].size = 4 + 4;
if (ecb->outf(ecb->priv, mb, 1) < 0) {
xrab_free_cpyarena(&aca);
return -1;
}
for (cpos = 0, i = 0; i < aca.cnt; i++) {
rcpy = aca.acpy + i;
if (rcpy->len == 0)
continue;
if (cpos < rcpy->tgt) {
size = rcpy->tgt - cpos;
if (size > 255) {
cpybuf[0] = XDL_BDOP_INSB;
XDL_LE32_PUT(cpybuf + 1, size);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_INSBOP_SIZE;
} else {
cpybuf[0] = XDL_BDOP_INS;
cpybuf[1] = (unsigned char) size;
mb[0].ptr = (char *) cpybuf;
mb[0].size = 2;
}
mb[1].ptr = mmb2->ptr + cpos;
mb[1].size = size;
if (ecb->outf(ecb->priv, mb, 2) < 0) {
xrab_free_cpyarena(&aca);
return -1;
}
cpos = rcpy->tgt;
}
cpybuf[0] = XDL_BDOP_CPY;
XDL_LE32_PUT(cpybuf + 1, rcpy->src);
XDL_LE32_PUT(cpybuf + 5, rcpy->len);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_COPYOP_SIZE;
if (ecb->outf(ecb->priv, mb, 1) < 0) {
xrab_free_cpyarena(&aca);
return -1;
}
cpos += rcpy->len;
}
xrab_free_cpyarena(&aca);
if (cpos < mmb2->size) {
size = mmb2->size - cpos;
if (size > 255) {
cpybuf[0] = XDL_BDOP_INSB;
XDL_LE32_PUT(cpybuf + 1, size);
mb[0].ptr = (char *) cpybuf;
mb[0].size = XDL_INSBOP_SIZE;
} else {
cpybuf[0] = XDL_BDOP_INS;
cpybuf[1] = (unsigned char) size;
mb[0].ptr = (char *) cpybuf;
mb[0].size = 2;
}
mb[1].ptr = mmb2->ptr + cpos;
mb[1].size = size;
if (ecb->outf(ecb->priv, mb, 2) < 0)
return -1;
}
return 0;
}
int xdl_rabdiff(mmfile_t *mmf1, mmfile_t *mmf2, xdemitcb_t *ecb) {
mmbuffer_t mmb1, mmb2;
if (!xdl_mmfile_iscompact(mmf1) || !xdl_mmfile_iscompact(mmf2))
return -1;
if ((mmb1.ptr = (char *) xdl_mmfile_first(mmf1, &mmb1.size)) == NULL)
mmb1.size = 0;
if ((mmb2.ptr = (char *) xdl_mmfile_first(mmf2, &mmb2.size)) == NULL)
mmb2.size = 0;
return xdl_rabdiff_mb(&mmb1, &mmb2, ecb);
}

View File

@ -0,0 +1,298 @@
#if defined(XRABPLY_TYPE64)
#if !defined(XV64)
#define XV64(v) ((xply_word) v ## ULL)
#endif
#define XRAB_ROOTPOLY XV64(0x36f7381af4d70d33)
#define XRAB_SHIFT 53
#define XRAB_WNDSIZE 20
typedef unsigned XRABPLY_TYPE64 xply_word;
static const xply_word T[256] = {
XV64(0x0), XV64(0x36f7381af4d70d33), XV64(0x5b19482f1d791755), XV64(0x6dee7035e9ae1a66),
XV64(0x80c5a844ce252399), XV64(0xb632905e3af22eaa), XV64(0xdbdce06bd35c34cc), XV64(0xed2bd871278b39ff),
XV64(0x18b50899c4a4732), XV64(0x377c6893689d4a01), XV64(0x5a9218a681335067), XV64(0x6c6520bc75e45d54),
XV64(0x814ef8cd526f64ab), XV64(0xb7b9c0d7a6b86998), XV64(0xda57b0e24f1673fe), XV64(0xeca088f8bbc17ecd),
XV64(0x316a11338948e64), XV64(0x35e19909cc438357), XV64(0x580fe93c25ed9931), XV64(0x6ef8d126d13a9402),
XV64(0x83d30957f6b1adfd), XV64(0xb524314d0266a0ce), XV64(0xd8ca4178ebc8baa8), XV64(0xee3d79621f1fb79b),
XV64(0x29df19aa4dec956), XV64(0x346ac9805009c465), XV64(0x5984b9b5b9a7de03), XV64(0x6f7381af4d70d330),
XV64(0x825859de6afbeacf), XV64(0xb4af61c49e2ce7fc), XV64(0xd94111f17782fd9a), XV64(0xefb629eb8355f0a9),
XV64(0x62d422671291cc8), XV64(0x30da7a3c85fe11fb), XV64(0x5d340a096c500b9d), XV64(0x6bc33213988706ae),
XV64(0x86e8ea62bf0c3f51), XV64(0xb01fd2784bdb3262), XV64(0xddf1a24da2752804), XV64(0xeb069a5756a22537),
XV64(0x7a612afed635bfa), XV64(0x31512ab519b456c9), XV64(0x5cbf5a80f01a4caf), XV64(0x6a48629a04cd419c),
XV64(0x8763baeb23467863), XV64(0xb19482f1d7917550), XV64(0xdc7af2c43e3f6f36), XV64(0xea8dcadecae86205),
XV64(0x53be33549bd92ac), XV64(0x33ccdb2fbd6a9f9f), XV64(0x5e22ab1a54c485f9), XV64(0x68d59300a01388ca),
XV64(0x85fe4b718798b135), XV64(0xb309736b734fbc06), XV64(0xdee7035e9ae1a660), XV64(0xe8103b446e36ab53),
XV64(0x4b0b3bcd5f7d59e), XV64(0x32478ba62120d8ad), XV64(0x5fa9fb93c88ec2cb), XV64(0x695ec3893c59cff8),
XV64(0x84751bf81bd2f607), XV64(0xb28223e2ef05fb34), XV64(0xdf6c53d706abe152), XV64(0xe99b6bcdf27cec61),
XV64(0xc5a844ce2523990), XV64(0x3aadbc56168534a3), XV64(0x5743cc63ff2b2ec5), XV64(0x61b4f4790bfc23f6),
XV64(0x8c9f2c082c771a09), XV64(0xba681412d8a0173a), XV64(0xd7866427310e0d5c), XV64(0xe1715c3dc5d9006f),
XV64(0xdd1d4c57e187ea2), XV64(0x3b26ecdf8acf7391), XV64(0x56c89cea636169f7), XV64(0x603fa4f097b664c4),
XV64(0x8d147c81b03d5d3b), XV64(0xbbe3449b44ea5008), XV64(0xd60d34aead444a6e), XV64(0xe0fa0cb45993475d),
XV64(0xf4c255fdac6b7f4), XV64(0x39bb1d452e11bac7), XV64(0x54556d70c7bfa0a1), XV64(0x62a2556a3368ad92),
XV64(0x8f898d1b14e3946d), XV64(0xb97eb501e034995e), XV64(0xd490c534099a8338), XV64(0xe267fd2efd4d8e0b),
XV64(0xec775d6468cf0c6), XV64(0x38304dccb25bfdf5), XV64(0x55de3df95bf5e793), XV64(0x632905e3af22eaa0),
XV64(0x8e02dd9288a9d35f), XV64(0xb8f5e5887c7ede6c), XV64(0xd51b95bd95d0c40a), XV64(0xe3ecada76107c939),
XV64(0xa77c66a937b2558), XV64(0x3c80fe7067ac286b), XV64(0x516e8e458e02320d), XV64(0x6799b65f7ad53f3e),
XV64(0x8ab26e2e5d5e06c1), XV64(0xbc455634a9890bf2), XV64(0xd1ab260140271194), XV64(0xe75c1e1bb4f01ca7),
XV64(0xbfc96e30f31626a), XV64(0x3d0baef9fbe66f59), XV64(0x50e5decc1248753f), XV64(0x6612e6d6e69f780c),
XV64(0x8b393ea7c11441f3), XV64(0xbdce06bd35c34cc0), XV64(0xd0207688dc6d56a6), XV64(0xe6d74e9228ba5b95),
XV64(0x9616779abefab3c), XV64(0x3f965f635f38a60f), XV64(0x52782f56b696bc69), XV64(0x648f174c4241b15a),
XV64(0x89a4cf3d65ca88a5), XV64(0xbf53f727911d8596), XV64(0xd2bd871278b39ff0), XV64(0xe44abf088c6492c3),
XV64(0x8ea37f037a5ec0e), XV64(0x3e1d0feac372e13d), XV64(0x53f37fdf2adcfb5b), XV64(0x650447c5de0bf668),
XV64(0x882f9fb4f980cf97), XV64(0xbed8a7ae0d57c2a4), XV64(0xd336d79be4f9d8c2), XV64(0xe5c1ef81102ed5f1),
XV64(0x18b50899c4a47320), XV64(0x2e42308330737e13), XV64(0x43ac40b6d9dd6475), XV64(0x755b78ac2d0a6946),
XV64(0x9870a0dd0a8150b9), XV64(0xae8798c7fe565d8a), XV64(0xc369e8f217f847ec), XV64(0xf59ed0e8e32f4adf),
XV64(0x193e581058ee3412), XV64(0x2fc9600aac393921), XV64(0x4227103f45972347), XV64(0x74d02825b1402e74),
XV64(0x99fbf05496cb178b), XV64(0xaf0cc84e621c1ab8), XV64(0xc2e2b87b8bb200de), XV64(0xf41580617f650ded),
XV64(0x1ba3a98afc30fd44), XV64(0x2d54919008e7f077), XV64(0x40bae1a5e149ea11), XV64(0x764dd9bf159ee722),
XV64(0x9b6601ce3215dedd), XV64(0xad9139d4c6c2d3ee), XV64(0xc07f49e12f6cc988), XV64(0xf68871fbdbbbc4bb),
XV64(0x1a28f903607aba76), XV64(0x2cdfc11994adb745), XV64(0x4131b12c7d03ad23), XV64(0x77c6893689d4a010),
XV64(0x9aed5147ae5f99ef), XV64(0xac1a695d5a8894dc), XV64(0xc1f41968b3268eba), XV64(0xf703217247f18389),
XV64(0x1e984abfb58d6fe8), XV64(0x286f72a5415a62db), XV64(0x45810290a8f478bd), XV64(0x73763a8a5c23758e),
XV64(0x9e5de2fb7ba84c71), XV64(0xa8aadae18f7f4142), XV64(0xc544aad466d15b24), XV64(0xf3b392ce92065617),
XV64(0x1f131a3629c728da), XV64(0x29e4222cdd1025e9), XV64(0x440a521934be3f8f), XV64(0x72fd6a03c06932bc),
XV64(0x9fd6b272e7e20b43), XV64(0xa9218a6813350670), XV64(0xc4cffa5dfa9b1c16), XV64(0xf238c2470e4c1125),
XV64(0x1d8eebac8d19e18c), XV64(0x2b79d3b679ceecbf), XV64(0x4697a3839060f6d9), XV64(0x70609b9964b7fbea),
XV64(0x9d4b43e8433cc215), XV64(0xabbc7bf2b7ebcf26), XV64(0xc6520bc75e45d540), XV64(0xf0a533ddaa92d873),
XV64(0x1c05bb251153a6be), XV64(0x2af2833fe584ab8d), XV64(0x471cf30a0c2ab1eb), XV64(0x71ebcb10f8fdbcd8),
XV64(0x9cc01361df768527), XV64(0xaa372b7b2ba18814), XV64(0xc7d95b4ec20f9272), XV64(0xf12e635436d89f41),
XV64(0x14ef8cd526f64ab0), XV64(0x2218b4cfd2214783), XV64(0x4ff6c4fa3b8f5de5), XV64(0x7901fce0cf5850d6),
XV64(0x942a2491e8d36929), XV64(0xa2dd1c8b1c04641a), XV64(0xcf336cbef5aa7e7c), XV64(0xf9c454a4017d734f),
XV64(0x1564dc5cbabc0d82), XV64(0x2393e4464e6b00b1), XV64(0x4e7d9473a7c51ad7), XV64(0x788aac69531217e4),
XV64(0x95a1741874992e1b), XV64(0xa3564c02804e2328), XV64(0xceb83c3769e0394e), XV64(0xf84f042d9d37347d),
XV64(0x17f92dc61e62c4d4), XV64(0x210e15dceab5c9e7), XV64(0x4ce065e9031bd381), XV64(0x7a175df3f7ccdeb2),
XV64(0x973c8582d047e74d), XV64(0xa1cbbd982490ea7e), XV64(0xcc25cdadcd3ef018), XV64(0xfad2f5b739e9fd2b),
XV64(0x16727d4f822883e6), XV64(0x2085455576ff8ed5), XV64(0x4d6b35609f5194b3), XV64(0x7b9c0d7a6b869980),
XV64(0x96b7d50b4c0da07f), XV64(0xa040ed11b8daad4c), XV64(0xcdae9d245174b72a), XV64(0xfb59a53ea5a3ba19),
XV64(0x12c2cef357df5678), XV64(0x2435f6e9a3085b4b), XV64(0x49db86dc4aa6412d), XV64(0x7f2cbec6be714c1e),
XV64(0x920766b799fa75e1), XV64(0xa4f05ead6d2d78d2), XV64(0xc91e2e98848362b4), XV64(0xffe9168270546f87),
XV64(0x13499e7acb95114a), XV64(0x25bea6603f421c79), XV64(0x4850d655d6ec061f), XV64(0x7ea7ee4f223b0b2c),
XV64(0x938c363e05b032d3), XV64(0xa57b0e24f1673fe0), XV64(0xc8957e1118c92586), XV64(0xfe62460bec1e28b5),
XV64(0x11d46fe06f4bd81c), XV64(0x272357fa9b9cd52f), XV64(0x4acd27cf7232cf49), XV64(0x7c3a1fd586e5c27a),
XV64(0x9111c7a4a16efb85), XV64(0xa7e6ffbe55b9f6b6), XV64(0xca088f8bbc17ecd0), XV64(0xfcffb79148c0e1e3),
XV64(0x105f3f69f3019f2e), XV64(0x26a8077307d6921d), XV64(0x4b467746ee78887b), XV64(0x7db14f5c1aaf8548),
XV64(0x909a972d3d24bcb7), XV64(0xa66daf37c9f3b184), XV64(0xcb83df02205dabe2), XV64(0xfd74e718d48aa6d1)
};
static const xply_word U[256] = {
XV64(0x0), XV64(0x1c3eb44b122426b2), XV64(0xe8a508cd09f4057), XV64(0x12b4e4c7c2bb66e5),
XV64(0x1d14a119a13e80ae), XV64(0x12a1552b31aa61c), XV64(0x139ef19571a1c0f9), XV64(0xfa045de6385e64b),
XV64(0xcde7a29b6aa0c6f), XV64(0x10e0ce62a48e2add), XV64(0x2542aa566354c38), XV64(0x1e6a9eee74116a8a),
XV64(0x11cadb3017948cc1), XV64(0xdf46f7b05b0aa73), XV64(0x1f408bbcc70bcc96), XV64(0x37e3ff7d52fea24),
XV64(0x19bcf4536d5418de), XV64(0x58240187f703e6c), XV64(0x1736a4dfbdcb5889), XV64(0xb081094afef7e3b),
XV64(0x4a8554acc6a9870), XV64(0x1896e101de4ebec2), XV64(0xa2205c61cf5d827), XV64(0x161cb18d0ed1fe95),
XV64(0x15628e7adbfe14b1), XV64(0x95c3a31c9da3203), XV64(0x1be8def60b6154e6), XV64(0x7d66abd19457254),
XV64(0x8762f637ac0941f), XV64(0x14489b2868e4b2ad), XV64(0x6fc7fefaa5fd448), XV64(0x1ac2cba4b87bf2fa),
XV64(0x58ed0bc2e7f3c8f), XV64(0x19b064f73c5b1a3d), XV64(0xb048030fee07cd8), XV64(0x173a347becc45a6a),
XV64(0x189a71a58f41bc21), XV64(0x4a4c5ee9d659a93), XV64(0x161021295fdefc76), XV64(0xa2e95624dfadac4),
XV64(0x950aa9598d530e0), XV64(0x156e1ede8af11652), XV64(0x7dafa19484a70b7), XV64(0x1be44e525a6e5605),
XV64(0x14440b8c39ebb04e), XV64(0x87abfc72bcf96fc), XV64(0x1ace5b00e974f019), XV64(0x6f0ef4bfb50d6ab),
XV64(0x1c3224ef432b2451), XV64(0xc90a4510f02e3), XV64(0x12b8746393b46406), XV64(0xe86c028819042b4),
XV64(0x12685f6e215a4ff), XV64(0x1d1831bdf031824d), XV64(0xfacd57a328ae4a8), XV64(0x1392613120aec21a),
XV64(0x10ec5ec6f581283e), XV64(0xcd2ea8de7a50e8c), XV64(0x1e660e4a251e6869), XV64(0x258ba01373a4edb),
XV64(0xdf8ffdf54bfa890), XV64(0x11c64b94469b8e22), XV64(0x372af538420e8c7), XV64(0x1f4c1b189604ce75),
XV64(0xb1da1785cfe791e), XV64(0x172315334eda5fac), XV64(0x597f1f48c613949), XV64(0x19a945bf9e451ffb),
XV64(0x16090061fdc0f9b0), XV64(0xa37b42aefe4df02), XV64(0x188350ed2d5fb9e7), XV64(0x4bde4a63f7b9f55),
XV64(0x7c3db51ea547571), XV64(0x1bfd6f1af87053c3), XV64(0x9498bdd3acb3526), XV64(0x15773f9628ef1394),
XV64(0x1ad77a484b6af5df), XV64(0x6e9ce03594ed36d), XV64(0x145d2ac49bf5b588), XV64(0x8639e8f89d1933a),
XV64(0x12a1552b31aa61c0), XV64(0xe9fe160238e4772), XV64(0x1c2b05a7e1352197), XV64(0x15b1ecf3110725),
XV64(0xfb5f4329094e16e), XV64(0x138b407982b0c7dc), XV64(0x13fa4be400ba139), XV64(0x1d0110f5522f878b),
XV64(0x1e7f2f0287006daf), XV64(0x2419b4995244b1d), XV64(0x10f57f8e579f2df8), XV64(0xccbcbc545bb0b4a),
XV64(0x36b8e1b263eed01), XV64(0x1f553a50341acbb3), XV64(0xde1de97f6a1ad56), XV64(0x11df6adce4858be4),
XV64(0xe9371c472814591), XV64(0x12adc58f60a56323), XV64(0x192148a21e05c6), XV64(0x1c279503b03a2374),
XV64(0x1387d0ddd3bfc53f), XV64(0xfb96496c19be38d), XV64(0x1d0d805103208568), XV64(0x133341a1104a3da),
XV64(0x24d0bedc42b49fe), XV64(0x1e73bfa6d60f6f4c), XV64(0xcc75b6114b409a9), XV64(0x10f9ef2a06902f1b),
XV64(0x1f59aaf46515c950), XV64(0x3671ebf7731efe2), XV64(0x11d3fa78b58a8907), XV64(0xded4e33a7aeafb5),
XV64(0x172f85971fd55d4f), XV64(0xb1131dc0df17bfd), XV64(0x19a5d51bcf4a1d18), XV64(0x59b6150dd6e3baa),
XV64(0xa3b248ebeebdde1), XV64(0x160590c5accffb53), XV64(0x4b174026e749db6), XV64(0x188fc0497c50bb04),
XV64(0x1bf1ffbea97f5120), XV64(0x7cf4bf5bb5b7792), XV64(0x157baf3279e01177), XV64(0x9451b796bc437c5),
XV64(0x6e55ea70841d18e), XV64(0x1adbeaec1a65f73c), XV64(0x86f0e2bd8de91d9), XV64(0x1451ba60cafab76b),
XV64(0x163b42f0b9fcf23c), XV64(0xa05f6bbabd8d48e), XV64(0x18b1127c6963b26b), XV64(0x48fa6377b4794d9),
XV64(0xb2fe3e918c27292), XV64(0x171157a20ae65420), XV64(0x5a5b365c85d32c5), XV64(0x199b072eda791477),
XV64(0x1ae538d90f56fe53), XV64(0x6db8c921d72d8e1), XV64(0x146f6855dfc9be04), XV64(0x851dc1ecded98b6),
XV64(0x7f199c0ae687efd), XV64(0x1bcf2d8bbc4c584f), XV64(0x97bc94c7ef73eaa), XV64(0x15457d076cd31818),
XV64(0xf87b6a3d4a8eae2), XV64(0x13b902e8c68ccc50), XV64(0x10de62f0437aab5), XV64(0x1d33526416138c07),
XV64(0x129317ba75966a4c), XV64(0xeada3f167b24cfe), XV64(0x1c194736a5092a1b), XV64(0x27f37db72d0ca9),
XV64(0x359cc8a6202e68d), XV64(0x1f6778c17026c03f), XV64(0xdd39c06b29da6da), XV64(0x11ed284da0b98068),
XV64(0x1e4d6d93c33c6623), XV64(0x273d9d8d1184091), XV64(0x10c73d1f13a32674), XV64(0xcf98954018700c6),
XV64(0x13b5924c9783ceb3), XV64(0xf8b260785a7e801), XV64(0x1d3fc2c0471c8ee4), XV64(0x101768b5538a856),
XV64(0xea1335536bd4e1d), XV64(0x129f871e249968af), XV64(0x2b63d9e6220e4a), XV64(0x1c15d792f40628f8),
XV64(0x1f6be8652129c2dc), XV64(0x3555c2e330de46e), XV64(0x11e1b8e9f1b6828b), XV64(0xddf0ca2e392a439),
XV64(0x27f497c80174272), XV64(0x1e41fd37923364c0), XV64(0xcf519f050880225), XV64(0x10cbadbb42ac2497),
XV64(0xa09661ffad7d66d), XV64(0x1637d254e8f3f0df), XV64(0x48336932a48963a), XV64(0x18bd82d8386cb088),
XV64(0x171dc7065be956c3), XV64(0xb23734d49cd7071), XV64(0x1997978a8b761694), XV64(0x5a923c199523026),
XV64(0x6d71c364c7dda02), XV64(0x1ae9a87d5e59fcb0), XV64(0x85d4cba9ce29a55), XV64(0x1463f8f18ec6bce7),
XV64(0x1bc3bd2fed435aac), XV64(0x7fd0964ff677c1e), XV64(0x1549eda33ddc1afb), XV64(0x97759e82ff83c49),
XV64(0x1d26e388e5028b22), XV64(0x11857c3f726ad90), XV64(0x13acb304359dcb75), XV64(0xf92074f27b9edc7),
XV64(0x324291443c0b8c), XV64(0x1c0cf6da56182d3e), XV64(0xeb8121d94a34bdb), XV64(0x1286a65686876d69),
XV64(0x11f899a153a8874d), XV64(0xdc62dea418ca1ff), XV64(0x1f72c92d8337c71a), XV64(0x34c7d669113e1a8),
XV64(0xcec38b8f29607e3), XV64(0x10d28cf3e0b22151), XV64(0x2666834220947b4), XV64(0x1e58dc7f302d6106),
XV64(0x49a17db885693fc), XV64(0x18a4a3909a72b54e), XV64(0xa10475758c9d3ab), XV64(0x162ef31c4aedf519),
XV64(0x198eb6c229681352), XV64(0x5b002893b4c35e0), XV64(0x1704e64ef9f75305), XV64(0xb3a5205ebd375b7),
XV64(0x8446df23efc9f93), XV64(0x147ad9b92cd8b921), XV64(0x6ce3d7eee63dfc4), XV64(0x1af08935fc47f976),
XV64(0x1550cceb9fc21f3d), XV64(0x96e78a08de6398f), XV64(0x1bda9c674f5d5f6a), XV64(0x7e4282c5d7979d8),
XV64(0x18a83334cb7db7ad), XV64(0x496877fd959911f), XV64(0x162263b81be2f7fa), XV64(0xa1cd7f309c6d148),
XV64(0x5bc922d6a433703), XV64(0x19822666786711b1), XV64(0xb36c2a1badc7754), XV64(0x170876eaa8f851e6),
XV64(0x1476491d7dd7bbc2), XV64(0x848fd566ff39d70), XV64(0x1afc1991ad48fb95), XV64(0x6c2addabf6cdd27),
XV64(0x962e804dce93b6c), XV64(0x155c5c4fcecd1dde), XV64(0x7e8b8880c767b3b), XV64(0x1bd60cc31e525d89),
XV64(0x114c767a629af73), XV64(0x1d2a732cb40d89c1), XV64(0xf9e97eb76b6ef24), XV64(0x13a023a06492c996),
XV64(0x1c00667e07172fdd), XV64(0x3ed2351533096f), XV64(0x128a36f2d7886f8a), XV64(0xeb482b9c5ac4938),
XV64(0xdcabd4e1083a31c), XV64(0x11f4090502a785ae), XV64(0x340edc2c01ce34b), XV64(0x1f7e5989d238c5f9),
XV64(0x10de1c57b1bd23b2), XV64(0xce0a81ca3990500), XV64(0x1e544cdb612263e5), XV64(0x26af89073064557)
};
#endif /* if defined(XRABPLY_TYPE64) */
#if defined(XRABPLY_TYPE32)
#if !defined(XV32)
#define XV32(v) ((xply_word) v ## ULL)
#endif
#define XRAB_ROOTPOLY XV32(0xabd1f37b)
#define XRAB_SHIFT 23
#define XRAB_WNDSIZE 20
typedef unsigned XRABPLY_TYPE32 xply_word;
static const xply_word T[256] = {
XV32(0x0), XV32(0xabd1f37b), XV32(0x57a3e6f6), XV32(0xfc72158d),
XV32(0x4963e97), XV32(0xaf47cdec), XV32(0x5335d861), XV32(0xf8e42b1a),
XV32(0x92c7d2e), XV32(0xa2fd8e55), XV32(0x5e8f9bd8), XV32(0xf55e68a3),
XV32(0xdba43b9), XV32(0xa66bb0c2), XV32(0x5a19a54f), XV32(0xf1c85634),
XV32(0x1258fa5c), XV32(0xb9890927), XV32(0x45fb1caa), XV32(0xee2aefd1),
XV32(0x16cec4cb), XV32(0xbd1f37b0), XV32(0x416d223d), XV32(0xeabcd146),
XV32(0x1b748772), XV32(0xb0a57409), XV32(0x4cd76184), XV32(0xe70692ff),
XV32(0x1fe2b9e5), XV32(0xb4334a9e), XV32(0x48415f13), XV32(0xe390ac68),
XV32(0x24b1f4b8), XV32(0x8f6007c3), XV32(0x7312124e), XV32(0xd8c3e135),
XV32(0x2027ca2f), XV32(0x8bf63954), XV32(0x77842cd9), XV32(0xdc55dfa2),
XV32(0x2d9d8996), XV32(0x864c7aed), XV32(0x7a3e6f60), XV32(0xd1ef9c1b),
XV32(0x290bb701), XV32(0x82da447a), XV32(0x7ea851f7), XV32(0xd579a28c),
XV32(0x36e90ee4), XV32(0x9d38fd9f), XV32(0x614ae812), XV32(0xca9b1b69),
XV32(0x327f3073), XV32(0x99aec308), XV32(0x65dcd685), XV32(0xce0d25fe),
XV32(0x3fc573ca), XV32(0x941480b1), XV32(0x6866953c), XV32(0xc3b76647),
XV32(0x3b534d5d), XV32(0x9082be26), XV32(0x6cf0abab), XV32(0xc72158d0),
XV32(0x4963e970), XV32(0xe2b21a0b), XV32(0x1ec00f86), XV32(0xb511fcfd),
XV32(0x4df5d7e7), XV32(0xe624249c), XV32(0x1a563111), XV32(0xb187c26a),
XV32(0x404f945e), XV32(0xeb9e6725), XV32(0x17ec72a8), XV32(0xbc3d81d3),
XV32(0x44d9aac9), XV32(0xef0859b2), XV32(0x137a4c3f), XV32(0xb8abbf44),
XV32(0x5b3b132c), XV32(0xf0eae057), XV32(0xc98f5da), XV32(0xa74906a1),
XV32(0x5fad2dbb), XV32(0xf47cdec0), XV32(0x80ecb4d), XV32(0xa3df3836),
XV32(0x52176e02), XV32(0xf9c69d79), XV32(0x5b488f4), XV32(0xae657b8f),
XV32(0x56815095), XV32(0xfd50a3ee), XV32(0x122b663), XV32(0xaaf34518),
XV32(0x6dd21dc8), XV32(0xc603eeb3), XV32(0x3a71fb3e), XV32(0x91a00845),
XV32(0x6944235f), XV32(0xc295d024), XV32(0x3ee7c5a9), XV32(0x953636d2),
XV32(0x64fe60e6), XV32(0xcf2f939d), XV32(0x335d8610), XV32(0x988c756b),
XV32(0x60685e71), XV32(0xcbb9ad0a), XV32(0x37cbb887), XV32(0x9c1a4bfc),
XV32(0x7f8ae794), XV32(0xd45b14ef), XV32(0x28290162), XV32(0x83f8f219),
XV32(0x7b1cd903), XV32(0xd0cd2a78), XV32(0x2cbf3ff5), XV32(0x876ecc8e),
XV32(0x76a69aba), XV32(0xdd7769c1), XV32(0x21057c4c), XV32(0x8ad48f37),
XV32(0x7230a42d), XV32(0xd9e15756), XV32(0x259342db), XV32(0x8e42b1a0),
XV32(0x3916219b), XV32(0x92c7d2e0), XV32(0x6eb5c76d), XV32(0xc5643416),
XV32(0x3d801f0c), XV32(0x9651ec77), XV32(0x6a23f9fa), XV32(0xc1f20a81),
XV32(0x303a5cb5), XV32(0x9bebafce), XV32(0x6799ba43), XV32(0xcc484938),
XV32(0x34ac6222), XV32(0x9f7d9159), XV32(0x630f84d4), XV32(0xc8de77af),
XV32(0x2b4edbc7), XV32(0x809f28bc), XV32(0x7ced3d31), XV32(0xd73cce4a),
XV32(0x2fd8e550), XV32(0x8409162b), XV32(0x787b03a6), XV32(0xd3aaf0dd),
XV32(0x2262a6e9), XV32(0x89b35592), XV32(0x75c1401f), XV32(0xde10b364),
XV32(0x26f4987e), XV32(0x8d256b05), XV32(0x71577e88), XV32(0xda868df3),
XV32(0x1da7d523), XV32(0xb6762658), XV32(0x4a0433d5), XV32(0xe1d5c0ae),
XV32(0x1931ebb4), XV32(0xb2e018cf), XV32(0x4e920d42), XV32(0xe543fe39),
XV32(0x148ba80d), XV32(0xbf5a5b76), XV32(0x43284efb), XV32(0xe8f9bd80),
XV32(0x101d969a), XV32(0xbbcc65e1), XV32(0x47be706c), XV32(0xec6f8317),
XV32(0xfff2f7f), XV32(0xa42edc04), XV32(0x585cc989), XV32(0xf38d3af2),
XV32(0xb6911e8), XV32(0xa0b8e293), XV32(0x5ccaf71e), XV32(0xf71b0465),
XV32(0x6d35251), XV32(0xad02a12a), XV32(0x5170b4a7), XV32(0xfaa147dc),
XV32(0x2456cc6), XV32(0xa9949fbd), XV32(0x55e68a30), XV32(0xfe37794b),
XV32(0x7075c8eb), XV32(0xdba43b90), XV32(0x27d62e1d), XV32(0x8c07dd66),
XV32(0x74e3f67c), XV32(0xdf320507), XV32(0x2340108a), XV32(0x8891e3f1),
XV32(0x7959b5c5), XV32(0xd28846be), XV32(0x2efa5333), XV32(0x852ba048),
XV32(0x7dcf8b52), XV32(0xd61e7829), XV32(0x2a6c6da4), XV32(0x81bd9edf),
XV32(0x622d32b7), XV32(0xc9fcc1cc), XV32(0x358ed441), XV32(0x9e5f273a),
XV32(0x66bb0c20), XV32(0xcd6aff5b), XV32(0x3118ead6), XV32(0x9ac919ad),
XV32(0x6b014f99), XV32(0xc0d0bce2), XV32(0x3ca2a96f), XV32(0x97735a14),
XV32(0x6f97710e), XV32(0xc4468275), XV32(0x383497f8), XV32(0x93e56483),
XV32(0x54c43c53), XV32(0xff15cf28), XV32(0x367daa5), XV32(0xa8b629de),
XV32(0x505202c4), XV32(0xfb83f1bf), XV32(0x7f1e432), XV32(0xac201749),
XV32(0x5de8417d), XV32(0xf639b206), XV32(0xa4ba78b), XV32(0xa19a54f0),
XV32(0x597e7fea), XV32(0xf2af8c91), XV32(0xedd991c), XV32(0xa50c6a67),
XV32(0x469cc60f), XV32(0xed4d3574), XV32(0x113f20f9), XV32(0xbaeed382),
XV32(0x420af898), XV32(0xe9db0be3), XV32(0x15a91e6e), XV32(0xbe78ed15),
XV32(0x4fb0bb21), XV32(0xe461485a), XV32(0x18135dd7), XV32(0xb3c2aeac),
XV32(0x4b2685b6), XV32(0xe0f776cd), XV32(0x1c856340), XV32(0xb754903b)
};
static const xply_word U[256] = {
XV32(0x0), XV32(0x5ce33923), XV32(0x1217813d), XV32(0x4ef4b81e),
XV32(0x242f027a), XV32(0x78cc3b59), XV32(0x36388347), XV32(0x6adbba64),
XV32(0x485e04f4), XV32(0x14bd3dd7), XV32(0x5a4985c9), XV32(0x6aabcea),
XV32(0x6c71068e), XV32(0x30923fad), XV32(0x7e6687b3), XV32(0x2285be90),
XV32(0x3b6dfa93), XV32(0x678ec3b0), XV32(0x297a7bae), XV32(0x7599428d),
XV32(0x1f42f8e9), XV32(0x43a1c1ca), XV32(0xd5579d4), XV32(0x51b640f7),
XV32(0x7333fe67), XV32(0x2fd0c744), XV32(0x61247f5a), XV32(0x3dc74679),
XV32(0x571cfc1d), XV32(0xbffc53e), XV32(0x450b7d20), XV32(0x19e84403),
XV32(0x76dbf526), XV32(0x2a38cc05), XV32(0x64cc741b), XV32(0x382f4d38),
XV32(0x52f4f75c), XV32(0xe17ce7f), XV32(0x40e37661), XV32(0x1c004f42),
XV32(0x3e85f1d2), XV32(0x6266c8f1), XV32(0x2c9270ef), XV32(0x707149cc),
XV32(0x1aaaf3a8), XV32(0x4649ca8b), XV32(0x8bd7295), XV32(0x545e4bb6),
XV32(0x4db60fb5), XV32(0x11553696), XV32(0x5fa18e88), XV32(0x342b7ab),
XV32(0x69990dcf), XV32(0x357a34ec), XV32(0x7b8e8cf2), XV32(0x276db5d1),
XV32(0x5e80b41), XV32(0x590b3262), XV32(0x17ff8a7c), XV32(0x4b1cb35f),
XV32(0x21c7093b), XV32(0x7d243018), XV32(0x33d08806), XV32(0x6f33b125),
XV32(0x46661937), XV32(0x1a852014), XV32(0x5471980a), XV32(0x892a129),
XV32(0x62491b4d), XV32(0x3eaa226e), XV32(0x705e9a70), XV32(0x2cbda353),
XV32(0xe381dc3), XV32(0x52db24e0), XV32(0x1c2f9cfe), XV32(0x40cca5dd),
XV32(0x2a171fb9), XV32(0x76f4269a), XV32(0x38009e84), XV32(0x64e3a7a7),
XV32(0x7d0be3a4), XV32(0x21e8da87), XV32(0x6f1c6299), XV32(0x33ff5bba),
XV32(0x5924e1de), XV32(0x5c7d8fd), XV32(0x4b3360e3), XV32(0x17d059c0),
XV32(0x3555e750), XV32(0x69b6de73), XV32(0x2742666d), XV32(0x7ba15f4e),
XV32(0x117ae52a), XV32(0x4d99dc09), XV32(0x36d6417), XV32(0x5f8e5d34),
XV32(0x30bdec11), XV32(0x6c5ed532), XV32(0x22aa6d2c), XV32(0x7e49540f),
XV32(0x1492ee6b), XV32(0x4871d748), XV32(0x6856f56), XV32(0x5a665675),
XV32(0x78e3e8e5), XV32(0x2400d1c6), XV32(0x6af469d8), XV32(0x361750fb),
XV32(0x5cccea9f), XV32(0x2fd3bc), XV32(0x4edb6ba2), XV32(0x12385281),
XV32(0xbd01682), XV32(0x57332fa1), XV32(0x19c797bf), XV32(0x4524ae9c),
XV32(0x2fff14f8), XV32(0x731c2ddb), XV32(0x3de895c5), XV32(0x610bace6),
XV32(0x438e1276), XV32(0x1f6d2b55), XV32(0x5199934b), XV32(0xd7aaa68),
XV32(0x67a1100c), XV32(0x3b42292f), XV32(0x75b69131), XV32(0x2955a812),
XV32(0x271dc115), XV32(0x7bfef836), XV32(0x350a4028), XV32(0x69e9790b),
XV32(0x332c36f), XV32(0x5fd1fa4c), XV32(0x11254252), XV32(0x4dc67b71),
XV32(0x6f43c5e1), XV32(0x33a0fcc2), XV32(0x7d5444dc), XV32(0x21b77dff),
XV32(0x4b6cc79b), XV32(0x178ffeb8), XV32(0x597b46a6), XV32(0x5987f85),
XV32(0x1c703b86), XV32(0x409302a5), XV32(0xe67babb), XV32(0x52848398),
XV32(0x385f39fc), XV32(0x64bc00df), XV32(0x2a48b8c1), XV32(0x76ab81e2),
XV32(0x542e3f72), XV32(0x8cd0651), XV32(0x4639be4f), XV32(0x1ada876c),
XV32(0x70013d08), XV32(0x2ce2042b), XV32(0x6216bc35), XV32(0x3ef58516),
XV32(0x51c63433), XV32(0xd250d10), XV32(0x43d1b50e), XV32(0x1f328c2d),
XV32(0x75e93649), XV32(0x290a0f6a), XV32(0x67feb774), XV32(0x3b1d8e57),
XV32(0x199830c7), XV32(0x457b09e4), XV32(0xb8fb1fa), XV32(0x576c88d9),
XV32(0x3db732bd), XV32(0x61540b9e), XV32(0x2fa0b380), XV32(0x73438aa3),
XV32(0x6aabcea0), XV32(0x3648f783), XV32(0x78bc4f9d), XV32(0x245f76be),
XV32(0x4e84ccda), XV32(0x1267f5f9), XV32(0x5c934de7), XV32(0x7074c4),
XV32(0x22f5ca54), XV32(0x7e16f377), XV32(0x30e24b69), XV32(0x6c01724a),
XV32(0x6dac82e), XV32(0x5a39f10d), XV32(0x14cd4913), XV32(0x482e7030),
XV32(0x617bd822), XV32(0x3d98e101), XV32(0x736c591f), XV32(0x2f8f603c),
XV32(0x4554da58), XV32(0x19b7e37b), XV32(0x57435b65), XV32(0xba06246),
XV32(0x2925dcd6), XV32(0x75c6e5f5), XV32(0x3b325deb), XV32(0x67d164c8),
XV32(0xd0adeac), XV32(0x51e9e78f), XV32(0x1f1d5f91), XV32(0x43fe66b2),
XV32(0x5a1622b1), XV32(0x6f51b92), XV32(0x4801a38c), XV32(0x14e29aaf),
XV32(0x7e3920cb), XV32(0x22da19e8), XV32(0x6c2ea1f6), XV32(0x30cd98d5),
XV32(0x12482645), XV32(0x4eab1f66), XV32(0x5fa778), XV32(0x5cbc9e5b),
XV32(0x3667243f), XV32(0x6a841d1c), XV32(0x2470a502), XV32(0x78939c21),
XV32(0x17a02d04), XV32(0x4b431427), XV32(0x5b7ac39), XV32(0x5954951a),
XV32(0x338f2f7e), XV32(0x6f6c165d), XV32(0x2198ae43), XV32(0x7d7b9760),
XV32(0x5ffe29f0), XV32(0x31d10d3), XV32(0x4de9a8cd), XV32(0x110a91ee),
XV32(0x7bd12b8a), XV32(0x273212a9), XV32(0x69c6aab7), XV32(0x35259394),
XV32(0x2ccdd797), XV32(0x702eeeb4), XV32(0x3eda56aa), XV32(0x62396f89),
XV32(0x8e2d5ed), XV32(0x5401ecce), XV32(0x1af554d0), XV32(0x46166df3),
XV32(0x6493d363), XV32(0x3870ea40), XV32(0x7684525e), XV32(0x2a676b7d),
XV32(0x40bcd119), XV32(0x1c5fe83a), XV32(0x52ab5024), XV32(0xe486907)
};
#endif /* if defined(XRABPLY_TYPE32) */

View File

@ -0,0 +1,68 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XTYPES_H)
#define XTYPES_H
typedef struct s_chanode {
struct s_chanode *next;
long icurr;
} chanode_t;
typedef struct s_chastore {
chanode_t *head, *tail;
long isize, nsize;
chanode_t *ancur;
chanode_t *sncur;
long scurr;
} chastore_t;
typedef struct s_xrecord {
struct s_xrecord *next;
char const *ptr;
long size;
unsigned long ha;
} xrecord_t;
typedef struct s_xdfile {
chastore_t rcha;
long nrec;
unsigned int hbits;
xrecord_t **rhash;
long dstart, dend;
xrecord_t **recs;
char *rchg;
long *rindex;
long nreff;
unsigned long *ha;
} xdfile_t;
typedef struct s_xdfenv {
xdfile_t xdf1, xdf2;
} xdfenv_t;
#endif /* #if !defined(XTYPES_H) */

580
src/libxdiff/xdiff/xutils.c Normal file
View File

@ -0,0 +1,580 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
#define XDL_GUESS_NLINES 256
long xdl_bogosqrt(long n) {
long i;
/*
* Classical integer square root approximation using shifts.
*/
for (i = 1; n > 0; n >>= 2)
i <<= 1;
return i;
}
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
xdemitcb_t *ecb) {
int i = 2;
mmbuffer_t mb[3];
mb[0].ptr = (char *) pre;
mb[0].size = psize;
mb[1].ptr = (char *) rec;
mb[1].size = size;
if (size > 0 && rec[size - 1] != '\n') {
mb[2].ptr = (char *) "\n\\ No newline at end of file\n";
mb[2].size = strlen(mb[2].ptr);
i++;
}
if (ecb->outf(ecb->priv, mb, i) < 0) {
return -1;
}
return 0;
}
int xdl_init_mmfile(mmfile_t *mmf, long bsize, unsigned long flags) {
mmf->flags = flags;
mmf->head = mmf->tail = NULL;
mmf->bsize = bsize;
mmf->fsize = 0;
mmf->rcur = mmf->wcur = NULL;
mmf->rpos = 0;
return 0;
}
void xdl_free_mmfile(mmfile_t *mmf) {
mmblock_t *cur, *tmp;
for (cur = mmf->head; (tmp = cur) != NULL;) {
cur = cur->next;
xdl_free(tmp);
}
}
int xdl_mmfile_iscompact(mmfile_t *mmf) {
return mmf->head == mmf->tail;
}
int xdl_seek_mmfile(mmfile_t *mmf, long off) {
long bsize;
if (xdl_mmfile_first(mmf, &bsize)) {
do {
if (off < bsize) {
mmf->rpos = off;
return 0;
}
off -= bsize;
} while (xdl_mmfile_next(mmf, &bsize));
}
return -1;
}
long xdl_read_mmfile(mmfile_t *mmf, void *data, long size) {
long rsize, csize;
char *ptr = data;
mmblock_t *rcur;
for (rsize = 0, rcur = mmf->rcur; rcur && rsize < size;) {
if (mmf->rpos >= rcur->size) {
if (!(mmf->rcur = rcur = rcur->next))
break;
mmf->rpos = 0;
}
csize = XDL_MIN(size - rsize, rcur->size - mmf->rpos);
memcpy(ptr, rcur->ptr + mmf->rpos, csize);
rsize += csize;
ptr += csize;
mmf->rpos += csize;
}
return rsize;
}
long xdl_write_mmfile(mmfile_t *mmf, void const *data, long size) {
long wsize, bsize, csize;
mmblock_t *wcur;
for (wsize = 0; wsize < size;) {
wcur = mmf->wcur;
if (wcur && (wcur->flags & XDL_MMB_READONLY))
return wsize;
if (!wcur || wcur->size == wcur->bsize ||
(mmf->flags & XDL_MMF_ATOMIC && wcur->size + size > wcur->bsize)) {
bsize = XDL_MAX(mmf->bsize, size);
if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t) + bsize))) {
return wsize;
}
wcur->flags = 0;
wcur->ptr = (char *) wcur + sizeof(mmblock_t);
wcur->size = 0;
wcur->bsize = bsize;
wcur->next = NULL;
if (!mmf->head)
mmf->head = wcur;
if (mmf->tail)
mmf->tail->next = wcur;
mmf->tail = wcur;
mmf->wcur = wcur;
}
csize = XDL_MIN(size - wsize, wcur->bsize - wcur->size);
memcpy(wcur->ptr + wcur->size, (char const *) data + wsize, csize);
wsize += csize;
wcur->size += csize;
mmf->fsize += csize;
}
return size;
}
long xdl_writem_mmfile(mmfile_t *mmf, mmbuffer_t *mb, int nbuf) {
int i;
long size;
char *data;
for (i = 0, size = 0; i < nbuf; i++)
size += mb[i].size;
if (!(data = (char *) xdl_mmfile_writeallocate(mmf, size)))
return -1;
for (i = 0; i < nbuf; i++) {
memcpy(data, mb[i].ptr, mb[i].size);
data += mb[i].size;
}
return size;
}
void *xdl_mmfile_writeallocate(mmfile_t *mmf, long size) {
long bsize;
mmblock_t *wcur;
char *blk;
if (!(wcur = mmf->wcur) || wcur->size + size > wcur->bsize) {
bsize = XDL_MAX(mmf->bsize, size);
if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t) + bsize))) {
return NULL;
}
wcur->flags = 0;
wcur->ptr = (char *) wcur + sizeof(mmblock_t);
wcur->size = 0;
wcur->bsize = bsize;
wcur->next = NULL;
if (!mmf->head)
mmf->head = wcur;
if (mmf->tail)
mmf->tail->next = wcur;
mmf->tail = wcur;
mmf->wcur = wcur;
}
blk = wcur->ptr + wcur->size;
wcur->size += size;
mmf->fsize += size;
return blk;
}
long xdl_mmfile_ptradd(mmfile_t *mmf, char *ptr, long size, unsigned long flags) {
mmblock_t *wcur;
if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t)))) {
return -1;
}
wcur->flags = flags;
wcur->ptr = ptr;
wcur->size = wcur->bsize = size;
wcur->next = NULL;
if (!mmf->head)
mmf->head = wcur;
if (mmf->tail)
mmf->tail->next = wcur;
mmf->tail = wcur;
mmf->wcur = wcur;
mmf->fsize += size;
return size;
}
long xdl_copy_mmfile(mmfile_t *mmf, long size, xdemitcb_t *ecb) {
long rsize, csize;
mmblock_t *rcur;
mmbuffer_t mb;
for (rsize = 0, rcur = mmf->rcur; rcur && rsize < size;) {
if (mmf->rpos >= rcur->size) {
if (!(mmf->rcur = rcur = rcur->next))
break;
mmf->rpos = 0;
}
csize = XDL_MIN(size - rsize, rcur->size - mmf->rpos);
mb.ptr = rcur->ptr + mmf->rpos;
mb.size = csize;
if (ecb->outf(ecb->priv, &mb, 1) < 0) {
return rsize;
}
rsize += csize;
mmf->rpos += csize;
}
return rsize;
}
void *xdl_mmfile_first(mmfile_t *mmf, long *size) {
if (!(mmf->rcur = mmf->head))
return NULL;
*size = mmf->rcur->size;
return mmf->rcur->ptr;
}
void *xdl_mmfile_next(mmfile_t *mmf, long *size) {
if (!mmf->rcur || !(mmf->rcur = mmf->rcur->next))
return NULL;
*size = mmf->rcur->size;
return mmf->rcur->ptr;
}
long xdl_mmfile_size(mmfile_t *mmf) {
return mmf->fsize;
}
int xdl_mmfile_cmp(mmfile_t *mmf1, mmfile_t *mmf2) {
int cres;
long size, bsize1, bsize2, size1, size2;
char const *blk1, *cur1, *top1;
char const *blk2, *cur2, *top2;
if ((cur1 = blk1 = xdl_mmfile_first(mmf1, &bsize1)) != NULL)
top1 = blk1 + bsize1;
if ((cur2 = blk2 = xdl_mmfile_first(mmf2, &bsize2)) != NULL)
top2 = blk2 + bsize2;
if (!cur1) {
if (!cur2 || xdl_mmfile_size(mmf2) == 0)
return 0;
return -*cur2;
} else if (!cur2)
return xdl_mmfile_size(mmf1) ? *cur1: 0;
for (;;) {
if (cur1 >= top1) {
if ((cur1 = blk1 = xdl_mmfile_next(mmf1, &bsize1)) != NULL)
top1 = blk1 + bsize1;
}
if (cur2 >= top2) {
if ((cur2 = blk2 = xdl_mmfile_next(mmf2, &bsize2)) != NULL)
top2 = blk2 + bsize2;
}
if (!cur1) {
if (!cur2)
break;
return -*cur2;
} else if (!cur2)
return *cur1;
size1 = top1 - cur1;
size2 = top2 - cur2;
size = XDL_MIN(size1, size2);
if ((cres = memcmp(cur1, cur2, size)) != 0)
return cres;
cur1 += size;
cur2 += size;
}
return 0;
}
int xdl_mmfile_compact(mmfile_t *mmfo, mmfile_t *mmfc, long bsize, unsigned long flags) {
long fsize = xdl_mmfile_size(mmfo), size;
char *data;
char const *blk;
if (xdl_init_mmfile(mmfc, bsize, flags) < 0) {
return -1;
}
if (!(data = (char *) xdl_mmfile_writeallocate(mmfc, fsize))) {
xdl_free_mmfile(mmfc);
return -1;
}
if ((blk = (char const *) xdl_mmfile_first(mmfo, &size)) != NULL) {
do {
memcpy(data, blk, size);
data += size;
} while ((blk = (char const *) xdl_mmfile_next(mmfo, &size)) != NULL);
}
return 0;
}
int xdl_mmfile_outf(void *priv, mmbuffer_t *mb, int nbuf) {
mmfile_t *mmf = priv;
if (xdl_writem_mmfile(mmf, mb, nbuf) < 0) {
return -1;
}
return 0;
}
int xdl_cha_init(chastore_t *cha, long isize, long icount) {
cha->head = cha->tail = NULL;
cha->isize = isize;
cha->nsize = icount * isize;
cha->ancur = cha->sncur = NULL;
cha->scurr = 0;
return 0;
}
void xdl_cha_free(chastore_t *cha) {
chanode_t *cur, *tmp;
for (cur = cha->head; (tmp = cur) != NULL;) {
cur = cur->next;
xdl_free(tmp);
}
}
void *xdl_cha_alloc(chastore_t *cha) {
chanode_t *ancur;
void *data;
if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {
return NULL;
}
ancur->icurr = 0;
ancur->next = NULL;
if (cha->tail)
cha->tail->next = ancur;
if (!cha->head)
cha->head = ancur;
cha->tail = ancur;
cha->ancur = ancur;
}
data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
ancur->icurr += cha->isize;
return data;
}
void *xdl_cha_first(chastore_t *cha) {
chanode_t *sncur;
if (!(cha->sncur = sncur = cha->head))
return NULL;
cha->scurr = 0;
return (char *) sncur + sizeof(chanode_t) + cha->scurr;
}
void *xdl_cha_next(chastore_t *cha) {
chanode_t *sncur;
if (!(sncur = cha->sncur))
return NULL;
cha->scurr += cha->isize;
if (cha->scurr == sncur->icurr) {
if (!(sncur = cha->sncur = sncur->next))
return NULL;
cha->scurr = 0;
}
return (char *) sncur + sizeof(chanode_t) + cha->scurr;
}
long xdl_guess_lines(mmfile_t *mf) {
long nl = 0, size, tsize = 0;
char const *data, *cur, *top;
if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
for (top = data + size; nl < XDL_GUESS_NLINES;) {
if (cur >= top) {
tsize += (long) (cur - data);
if (!(cur = data = xdl_mmfile_next(mf, &size)))
break;
top = data + size;
}
nl++;
if (!(cur = memchr(cur, '\n', top - cur)))
cur = top;
else
cur++;
}
tsize += (long) (cur - data);
}
if (nl && tsize)
nl = xdl_mmfile_size(mf) / (tsize / nl);
return nl + 1;
}
unsigned long xdl_hash_record(char const **data, char const *top) {
unsigned long ha = 5381;
char const *ptr = *data;
for (; ptr < top && *ptr != '\n'; ptr++) {
ha += (ha << 5);
ha ^= (unsigned long) *ptr;
}
*data = ptr < top ? ptr + 1: ptr;
return ha;
}
unsigned int xdl_hashbits(unsigned int size) {
unsigned int val = 1, bits = 0;
for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++);
return bits ? bits: 1;
}
int xdl_num_out(char *out, long val) {
char *ptr, *str = out;
char buf[32];
ptr = buf + sizeof(buf) - 1;
*ptr = '\0';
if (val < 0) {
*--ptr = '-';
val = -val;
}
for (; val && ptr > buf; val /= 10)
*--ptr = "0123456789"[val % 10];
if (*ptr)
for (; *ptr; ptr++, str++)
*str = *ptr;
else
*str++ = '0';
*str = '\0';
return str - out;
}
long xdl_atol(char const *str, char const **next) {
long val, base;
char const *top;
for (top = str; XDL_ISDIGIT(*top); top++);
if (next)
*next = top;
for (val = 0, base = 1, top--; top >= str; top--, base *= 10)
val += base * (long)(*top - '0');
return val;
}
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb) {
int nb = 0;
mmbuffer_t mb;
char buf[128];
memcpy(buf, "@@ -", 4);
nb += 4;
nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1);
memcpy(buf + nb, ",", 1);
nb += 1;
nb += xdl_num_out(buf + nb, c1);
memcpy(buf + nb, " +", 2);
nb += 2;
nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1);
memcpy(buf + nb, ",", 1);
nb += 1;
nb += xdl_num_out(buf + nb, c2);
memcpy(buf + nb, " @@\n", 4);
nb += 4;
mb.ptr = buf;
mb.size = nb;
if (ecb->outf(ecb->priv, &mb, 1) < 0)
return -1;
return 0;
}

View File

@ -0,0 +1,47 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#if !defined(XUTILS_H)
#define XUTILS_H
long xdl_bogosqrt(long n);
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
xdemitcb_t *ecb);
int xdl_mmfile_outf(void *priv, mmbuffer_t *mb, int nbuf);
int xdl_cha_init(chastore_t *cha, long isize, long icount);
void xdl_cha_free(chastore_t *cha);
void *xdl_cha_alloc(chastore_t *cha);
void *xdl_cha_first(chastore_t *cha);
void *xdl_cha_next(chastore_t *cha);
long xdl_guess_lines(mmfile_t *mf);
unsigned long xdl_hash_record(char const **data, char const *top);
unsigned int xdl_hashbits(unsigned int size);
int xdl_num_out(char *out, long val);
long xdl_atol(char const *str, char const **next);
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb);
#endif /* #if !defined(XUTILS_H) */

View File

@ -0,0 +1,27 @@
/*
* LibXDiff by Davide Libenzi ( File Differential Library )
* Copyright (C) 2003 Davide Libenzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@xmailserver.org>
*
*/
#include "xinclude.h"
char libxdiff_version[] = "LibXDiff v" PACKAGE_VERSION " by Davide Libenzi <davide@xmailserver.org>";

View File

@ -1,9 +1,9 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "gpuvendor.h"
EmulatorConfig config = {0};
@ -64,6 +64,18 @@ static int detectGame(uint32_t elf_crc)
}
break;
case THE_HOUSE_OF_THE_DEAD_4_REVB:
case THE_HOUSE_OF_THE_DEAD_4_REVB_TEST:
{
config.gameTitle = "The House of the Dead 4 Rev B";
config.gameID = "SBLC";
config.gameDVP = "DVP-0003B";
config.gameType = SHOOTING;
config.gameStatus = WORKING;
return 0;
}
break;
case THE_HOUSE_OF_THE_DEAD_4_REVC:
case THE_HOUSE_OF_THE_DEAD_4_REVC_TEST:
{
@ -81,6 +93,21 @@ static int detectGame(uint32_t elf_crc)
{
config.gameTitle = "The House of the Dead 4 Special";
config.emulateRideboard = 1;
config.gameID = "SBLS";
config.gameDVP = "DVP-0010";
config.gameStatus = WORKING;
config.width = 1024;
config.height = 768;
return 0;
}
break;
case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB:
case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB_TEST:
{
config.gameTitle = "The House of the Dead 4 Special Rev B";
config.emulateRideboard = 1;
config.gameDVP = "DVP-0010B";
config.gameStatus = WORKING;
config.width = 1024;
config.height = 768;
@ -94,6 +121,8 @@ static int detectGame(uint32_t elf_crc)
{
config.gameTitle = "The House of the Dead EX";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0063";
config.gameID = "SBRC";
return 0;
}
break;
@ -101,7 +130,7 @@ static int detectGame(uint32_t elf_crc)
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_REVA_TEST:
{
config.gameTitle = "Outrun 2 SP SDX";
config.gameTitle = "Outrun 2 SP SDX Rev A";
config.gameDVP = "DVP-0015A";
config.gameID = "SBMB";
config.emulateDriveboard = 1;
@ -112,6 +141,61 @@ static int detectGame(uint32_t elf_crc)
}
break;
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_TEST:
{
config.gameTitle = "Outrun 2 SP SDX";
config.gameDVP = "DVP-0015";
config.gameID = "SBMB";
config.emulateDriveboard = 1;
config.emulateMotionboard = 1;
config.gameStatus = WORKING;
config.gameType = DRIVING;
return 0;
}
break;
case VIRTUA_FIGHTER_5:
{
config.gameTitle = "Virtua Fighter 5";
config.gameDVP = "DVP-0008";
config.gameID = "SBLM";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_REVA:
{
config.gameTitle = "Virtua Fighter 5 Rev A";
config.gameDVP = "DVP-0008A";
config.gameID = "SBLM";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_REVB:
{
config.gameTitle = "Virtua Fighter 5 Rev B";
config.gameDVP = "DVP-0008B";
config.gameID = "SBLM";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_REVE:
{
config.gameTitle = "Virtua Fighter 5 Rev E (Public Version C)";
config.gameDVP = "DVP-0008E";
config.gameID = "SBLM";
config.gameStatus = WORKING;
config.gameType = FIGHTING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_EXPORT:
{
config.gameTitle = "Virtua Fighter 5 Export";
@ -126,9 +210,20 @@ static int detectGame(uint32_t elf_crc)
config.gameTitle = "Virtua Fighter 5 R";
config.gameDVP = "DVP-XXXX";
config.gameID = "SBQU";
config.gameStatus = NOT_WORKING;
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_R_REVD:
{
config.gameTitle = "Virtua Fighter 5 R Rev D";
config.gameDVP = "DVP-XXXX";
config.gameID = "SBQU";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN:
{
@ -137,6 +232,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBUV";
return 0;
}
break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA:
{
@ -145,6 +241,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBUV";
return 0;
}
break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB:
{
@ -153,11 +250,22 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBUV";
return 0;
}
break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000:
{
config.gameTitle = "Virtua Fighter 5 Final Showdown REV B ver 6.0000";
config.gameDVP = "DVP-5020";
config.gameID = "SBUV";
return 0;
}
break;
case LETS_GO_JUNGLE:
{
config.gameTitle = "Let's Go Jungle! Lost on the Island of Spice!";
config.gameDVP = "DVP-0011";
config.gameID = "SBLU";
config.gameStatus = WORKING;
return 0;
}
@ -167,6 +275,7 @@ static int detectGame(uint32_t elf_crc)
{
config.gameTitle = "Let's Go Jungle! Special!";
config.emulateRideboard = 1;
config.gameID = "SBNR";
config.gameStatus = WORKING;
return 0;
}
@ -175,7 +284,11 @@ static int detectGame(uint32_t elf_crc)
case AFTER_BURNER_CLIMAX:
{
config.gameTitle = "After Burner Climax";
config.gameDVP = "DVP-0009";
config.gameID = "SBLR";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
@ -183,7 +296,23 @@ static int detectGame(uint32_t elf_crc)
case AFTER_BURNER_CLIMAX_REVA:
{
config.gameTitle = "After Burner Climax Rev A";
config.gameDVP = "DVP-0009A";
config.gameID = "SBLR";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
case AFTER_BURNER_CLIMAX_REVB:
{
config.gameTitle = "After Burner Climax Rev B";
config.gameDVP = "DVP-0009B";
config.gameID = "SBLR";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
@ -191,32 +320,133 @@ static int detectGame(uint32_t elf_crc)
case AFTER_BURNER_CLIMAX_SDX:
{
config.gameTitle = "After Burner Climax SDX";
config.gameDVP = "DVP-0018-SDX";
config.gameID = "SBMN";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
case AFTER_BURNER_CLIMAX_CE:
case AFTER_BURNER_CLIMAX_SDX_REVA:
{
config.gameTitle = "After Burner Climax CE";
config.gameTitle = "After Burner Climax SDX Rev A";
config.gameDVP = "DVP-0018A-SDX";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
case INITIALD_4:
case AFTER_BURNER_CLIMAX_SE:
{
config.gameTitle = "Initial D Arcade Stage 4";
config.gameTitle = "After Burner Climax SE";
config.gameDVP = "DVP-0031";
config.gameID = "SBLR";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
case AFTER_BURNER_CLIMAX_SE_REVA:
{
config.gameTitle = "After Burner Climax SE Rev A";
config.gameDVP = "DVP-0031A";
config.gameID = "SBLR";
config.gameStatus = WORKING;
config.jvsIOType = SEGA_TYPE_1;
config.gameType = ABC;
return 0;
}
break;
case INITIALD_4_REVA:
{
config.gameTitle = "Initial D Arcade Stage 4 Rev A";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0019A";
config.gameID = "SBML";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_REVE:
case INITIALD_4_REVB:
{
config.gameTitle = "Initial D Arcade Stage 4 Rev E";
config.gameTitle = "Initial D Arcade Stage 4 Rev B";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0019B";
config.gameID = "SBML";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_REVC:
{
config.gameTitle = "Initial D Arcade Stage 4 Rev C";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0019C";
config.gameID = "SBML";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_REVD:
{
config.gameTitle = "Initial D Arcade Stage 4 Rev D";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0019D";
config.gameID = "SBML";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_REVG:
{
config.gameTitle = "Initial D Arcade Stage 4 Rev G";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0019G";
config.gameID = "SBML";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_EXP_REVB:
{
config.gameTitle = "Initial D Arcade Stage 4 Export Rev B";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0030B";
config.gameID = "SBNK";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_EXP_REVC:
{
config.gameTitle = "Initial D Arcade Stage 4 Export Rev C";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0030C";
config.gameID = "SBNK";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_4_EXP_REVD:
{
config.gameTitle = "Initial D Arcade Stage 4 Export Rev D";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0030D";
config.gameID = "SBNK";
config.gameType = DRIVING;
return 0;
}
@ -226,6 +456,7 @@ static int detectGame(uint32_t elf_crc)
{
config.gameTitle = "SEGA Race TV";
config.emulateDriveboard = 1;
config.gameDVP = "DVP-0044";
config.gameStatus = WORKING;
config.gameType = DRIVING;
return 0;
@ -254,9 +485,13 @@ static int detectGame(uint32_t elf_crc)
break;
case TOO_SPICY:
case TOO_SPICY_TEST:
{
config.gameTitle = "Too Spicy";
config.gameDVP = "DVP-0027A";
config.gameID = "SBMV";
config.gameStatus = WORKING;
config.gameType = SHOOTING;
return 0;
}
break;
@ -265,23 +500,42 @@ static int detectGame(uint32_t elf_crc)
case VIRTUA_TENNIS_3_TEST:
{
config.gameTitle = "Virtua Tennis 3";
config.gameDVP = "DVP-0005";
config.gameID = "SBKX";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_REVC:
case VIRTUA_TENNIS_3_REVA:
case VIRTUA_TENNIS_3_REVA_TEST:
{
config.gameTitle = "Virtua Fighter 5 Rev C";
config.gameTitle = "Virtua Tennis 3 Rev A";
config.gameDVP = "DVP-0005A";
config.gameID = "SBKX";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_FIGHTER_5_REVE:
case VIRTUA_TENNIS_3_REVB:
case VIRTUA_TENNIS_3_REVB_TEST:
{
config.gameTitle = "Virtua Fighter 5 Rev E";
config.gameStatus = NOT_WORKING;
config.gameTitle = "Virtua Tennis 3 Rev B";
config.gameDVP = "DVP-0005B";
config.gameID = "SBKX";
config.gameStatus = WORKING;
return 0;
}
break;
case VIRTUA_TENNIS_3_REVC:
case VIRTUA_TENNIS_3_REVC_TEST:
{
config.gameTitle = "Virtua Tennis 3 Rev C";
config.gameDVP = "DVP-0005C";
config.gameID = "SBKX";
config.gameStatus = WORKING;
return 0;
}
break;
@ -289,6 +543,8 @@ static int detectGame(uint32_t elf_crc)
case PRIMEVAL_HUNT:
{
config.gameTitle = "Primeval Hunt";
config.gameDVP = "DVP-0048A";
config.gameID = "SBPP";
config.gameStatus = WORKING;
config.gameType = SHOOTING;
return 0;
@ -301,23 +557,73 @@ static int detectGame(uint32_t elf_crc)
config.gameStatus = WORKING;
config.gameDVP = "DVP-0029A";
config.gameID = "SBNJ";
config.jvsAnalogueInBits = 8;
config.jvsIOType = SEGA_TYPE_1;
return 0;
}
break;
case INITIALD_5_EXP_20:
case INITIALD_5_JAP_REVA:
{
config.gameTitle = "Initial D Arcade Stage 5 Export Ver 2.0";
config.gameStatus = NOT_WORKING;
config.gameTitle = "Initial D Arcade Stage 5 Rev A";
config.gameDVP = "DVP-0070A";
config.gameID = "SBQZ";
config.gameStatus = WORKING;
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_ARCADE_STAGE_5:
case INITIALD_5_JAP_REVF:
{
config.gameTitle = "Initial D Arcade Stage 5";
config.gameStatus = NOT_WORKING;
config.gameTitle = "Initial D Arcade Stage 5 Rev F";
config.gameDVP = "DVP-0070F";
config.gameID = "SBQZ";
config.gameStatus = WORKING;
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_5_EXP_30:
{
config.gameTitle = "Initial D5 Ver 2.0";
config.gameStatus = WORKING;
config.gameDVP = "DVP-0075";
config.gameID = "SBTS";
config.gameType = DRIVING;
return 0;
}
break;
case INITIALD_5_EXP_40:
{
config.gameTitle = "Initial D5 5 Ver 4.0";
config.gameDVP = "DVP-0084A";
config.gameID = "SBQN";
config.gameStatus = WORKING;
config.gameType = DRIVING;
return 0;
}
break;
case HUMMER:
{
config.gameTitle = "Hummer";
config.gameID = "SBQN";
config.gameDVP = "DVP-0057B";
config.gameType = DRIVING;
config.gameStatus = WORKING;
return 0;
}
break;
case HUMMER_SDLX:
{
config.gameTitle = "Hummer SDLX";
config.gameID = "SBST";
config.gameDVP = "DVP-0057";
config.gameType = DRIVING;
config.gameStatus = WORKING;
return 0;
}
break;
@ -333,10 +639,32 @@ static int detectGame(uint32_t elf_crc)
}
break;
case HUMMER_EXTREME_MDX:
{
config.gameTitle = "Hummer Extreme MDX";
config.gameID = "SBST";
config.gameDVP = "DVP-0083";
config.gameType = DRIVING;
config.gameStatus = WORKING;
return 0;
}
break;
case LETS_GO_JUNGLE_REVA:
{
config.gameTitle = "Let's Go Jungle! Lost on the Island of Spice! Rev A";
config.gameDVP = "DVP-0011A";
config.gameID = "SBLU";
config.gameStatus = WORKING;
return 0;
}
break;
case HARLEY_DAVIDSON:
{
config.gameTitle = "Harley Davidson";
config.gameType = HARLEY;
config.gameDVP = "DVP-5007";
config.gameStatus = WORKING;
return 0;
}
@ -405,6 +733,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "FULLSCREEN") == 0)
config->fullscreen = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "NO_SDL") == 0)
config->noSDL = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "EMULATE_JVS") == 0)
config->emulateJVS = atoi(getNextToken(NULL, " ", &saveptr));
@ -443,9 +774,33 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "DEBUG_MSGS") == 0)
config->showDebugMessages = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "HUMMER_FLICKER_FIX") == 0)
config->hummerFlickerFix = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "KEEP_ASPECT_RATIO") == 0)
config->keepAspectRatio = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "GPU_VENDOR") == 0)
config->GPUVendor = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "OUTRUN_LENS_GLARE_ENABLED") == 0)
config->outrunLensGlareEnabled = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "FPS_LIMITER_ENABLED") == 0)
config->fpsLimiter = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "FPS_TARGET") == 0)
config->fpsTarget = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "LGJ_RENDER_WITH_MESA") == 0)
config->lgjRenderWithMesa = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "PRIMEVAL_HUNT_MODE") == 0)
config->phMode = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "TEST_KEY") == 0)
config->keymap.test = atoi(getNextToken(NULL, " ", &saveptr));
// TODO: add config when supporting player2
else if (strcmp(command, "PLAYER_1_START_KEY") == 0)
config->keymap.player1.start = atoi(getNextToken(NULL, " ", &saveptr));
@ -479,6 +834,117 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "PLAYER_1_BUTTON_4_KEY") == 0)
config->keymap.player1.button4 = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "PLAYER_1_BUTTON_5_KEY") == 0)
config->keymap.player1.button5 = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "PLAYER_1_BUTTON_6_KEY") == 0)
config->keymap.player1.button6 = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "PLAYER_1_BUTTON_7_KEY") == 0)
config->keymap.player1.button7 = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "PLAYER_1_BUTTON_8_KEY") == 0)
config->keymap.player1.button8 = atoi(getNextToken(NULL, " ", &saveptr));
// Player 1 controls
else if (strcmp(command, "PLAYER_1_BUTTON_START") == 0)
strncpy(config->arcadeInputs.player1_button_start, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_SERVICE") == 0)
strncpy(config->arcadeInputs.player1_button_service, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_UP") == 0)
strncpy(config->arcadeInputs.player1_button_up, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_DOWN") == 0)
strncpy(config->arcadeInputs.player1_button_down, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_LEFT") == 0)
strncpy(config->arcadeInputs.player1_button_left, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_RIGHT") == 0)
strncpy(config->arcadeInputs.player1_button_right, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_1") == 0)
strncpy(config->arcadeInputs.player1_button_1, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_2") == 0)
strncpy(config->arcadeInputs.player1_button_2, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_3") == 0)
strncpy(config->arcadeInputs.player1_button_3, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_4") == 0)
strncpy(config->arcadeInputs.player1_button_4, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_5") == 0)
strncpy(config->arcadeInputs.player1_button_5, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_6") == 0)
strncpy(config->arcadeInputs.player1_button_6, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_7") == 0)
strncpy(config->arcadeInputs.player1_button_7, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_8") == 0)
strncpy(config->arcadeInputs.player1_button_8, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_9") == 0)
strncpy(config->arcadeInputs.player1_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_10") == 0)
strncpy(config->arcadeInputs.player1_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
// Player 2 controls
else if (strcmp(command, "PLAYER_2_BUTTON_START") == 0)
strncpy(config->arcadeInputs.player2_button_start, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_SERVICE") == 0)
strncpy(config->arcadeInputs.player2_button_service, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_UP") == 0)
strncpy(config->arcadeInputs.player2_button_up, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_DOWN") == 0)
strncpy(config->arcadeInputs.player2_button_down, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_LEFT") == 0)
strncpy(config->arcadeInputs.player2_button_left, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_RIGHT") == 0)
strncpy(config->arcadeInputs.player2_button_right, getNextToken(NULL, " ", &saveptr),
INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_1") == 0)
strncpy(config->arcadeInputs.player2_button_1, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_2") == 0)
strncpy(config->arcadeInputs.player2_button_2, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_3") == 0)
strncpy(config->arcadeInputs.player2_button_3, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_4") == 0)
strncpy(config->arcadeInputs.player2_button_4, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_5") == 0)
strncpy(config->arcadeInputs.player2_button_5, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_6") == 0)
strncpy(config->arcadeInputs.player2_button_6, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_7") == 0)
strncpy(config->arcadeInputs.player2_button_7, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_8") == 0)
strncpy(config->arcadeInputs.player2_button_8, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_9") == 0)
strncpy(config->arcadeInputs.player2_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_10") == 0)
strncpy(config->arcadeInputs.player2_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
// Analogue inputs
else if (strcmp(command, "ANALOGUE_1") == 0)
strncpy(config->arcadeInputs.analogue_1, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_2") == 0)
strncpy(config->arcadeInputs.analogue_2, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_3") == 0)
strncpy(config->arcadeInputs.analogue_3, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_4") == 0)
strncpy(config->arcadeInputs.analogue_4, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_5") == 0)
strncpy(config->arcadeInputs.analogue_5, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_6") == 0)
strncpy(config->arcadeInputs.analogue_6, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_7") == 0)
strncpy(config->arcadeInputs.analogue_7, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "ANALOGUE_8") == 0)
strncpy(config->arcadeInputs.analogue_8, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "INPUT_MODE") == 0)
config->inputMode = atoi(getNextToken(NULL, " ", &saveptr));
else
printf("Error: Unknown settings command %s\n", command);
}
@ -500,18 +966,23 @@ KeyMapping getDefaultKeymap()
defaultKeyMapping.player1.button1 = 24;
defaultKeyMapping.player1.button2 = 25;
defaultKeyMapping.player1.button3 = 26;
defaultKeyMapping.player1.button4 = 27;
defaultKeyMapping.player2.start = -1;
defaultKeyMapping.player2.service = -1;
defaultKeyMapping.player2.coin = -1;
defaultKeyMapping.player2.up = -1;
defaultKeyMapping.player2.down = -1;
defaultKeyMapping.player2.left = -1;
defaultKeyMapping.player2.right = -1;
defaultKeyMapping.player2.button1 = -1;
defaultKeyMapping.player2.button2 = -1;
defaultKeyMapping.player2.button3 = -1;
defaultKeyMapping.player2.button4 = -1;
defaultKeyMapping.player1.button4 = 27; // R
defaultKeyMapping.player1.button5 = 40; // D
defaultKeyMapping.player1.button6 = 41;
defaultKeyMapping.player1.button7 = 42;
defaultKeyMapping.player1.button8 = 43;
defaultKeyMapping.player2.start = 60;
defaultKeyMapping.player2.service = 61;
defaultKeyMapping.player2.coin = 15;
defaultKeyMapping.player2.up = 54;
defaultKeyMapping.player2.down = 53;
defaultKeyMapping.player2.left = 55;
defaultKeyMapping.player2.right = 56;
defaultKeyMapping.player2.button1 = 52;
defaultKeyMapping.player2.button2 = 57;
defaultKeyMapping.player2.button3 = 58;
defaultKeyMapping.player2.button4 = 59; // ,
defaultKeyMapping.player2.button5 = 37; // CTRL
return defaultKeyMapping;
}
@ -530,21 +1001,35 @@ int initConfig()
strcpy(config.serial2Path, "/dev/ttyS1");
config.width = 640;
config.height = 480;
config.crc32 = elf_crc;
config.region = -1;
config.freeplay = -1;
config.showDebugMessages = 0;
config.hummerFlickerFix = 0;
config.keepAspectRatio = 0;
config.gameTitle = "Unknown game";
config.gameID = "XXXX";
config.gameDVP = "DVP-XXXX";
config.gameType = SHOOTING;
config.keymap = getDefaultKeymap();
config.jvsAnalogueInBits = 10;
config.jvsIOType = SEGA_TYPE_3;
config.outrunLensGlareEnabled = 1;
config.GPUVendor = AUTO_DETECT_GPU;
config.fpsLimiter = 0;
config.fpsTarget = 60;
config.lgjRenderWithMesa = 1;
config.noSDL = 0;
config.phMode = 1;
config.crc32 = elf_crc;
if (detectGame(config.crc32) != 0)
{
printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32);
printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: "
"https://github.com/lindbergh-loader/lindbergh-loader/issues/"
"new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n",
config.crc32, config.crc32);
}
config.inputMode = 0; // Default to all inputs
configFile = fopen(CONFIG_PATH, "r");
if (configFile == NULL)

View File

@ -1,136 +1,248 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <stdint.h>
#define MAX_PATH_LENGTH 1024
#define INPUT_STRING_LENGTH 256
#define AFTER_BURNER_CLIMAX 0xcc02de7d
#define AFTER_BURNER_CLIMAX_REVA 0x152530dd
#define AFTER_BURNER_CLIMAX_REVB 0x0002
#define AFTER_BURNER_CLIMAX_SDX 0x5c18953c
#define AFTER_BURNER_CLIMAX_SDX_REVA 0x0004
#define AFTER_BURNER_CLIMAX_CE 0x9af7cb29
#define GHOST_SQUAD_EVOLUTION 0xe60d8e04
#define HARLEY_DAVIDSON 0x0007
#define HUMMER 0x0008
#define HUMMER_EXTREME 0xc85f106a
#define HUMMER_EXTREME_MDX 0x0010
#define INITIALD_4 0x4e9ccf33
#define INITIALD_4_REVE 0x7f3f9f0c
#define INITIALD_5_EXP_20 0x14d1292a
#define INITIALD_ARCADE_STAGE_5 0x722ebbc4
#define LETS_GO_JUNGLE 0xd4726d61
#define LETS_GO_JUNGLE_REVA 0xB6479554
#define LETS_GO_JUNGLE_SPECIAL 0xbbabc0e0
#define OUTRUN_2_SP_SDX 0x0019
#define OUTRUN_2_SP_SDX_REVA 0x6d055308
#define OUTRUN_2_SP_SDX_REVA_TEST 0xffdccaaa
#define OUTRUN_2_SP_SDX_TEST 0x0022
#define PRIMEVAL_HUNT 0xcdbc8069
#define RAMBO 0x77ebac34
#define RAMBO_CHINA 0x0025
#define R_TUNED 0xb05d9bbe
#define SEGABOOT 0x0027
#define SEGABOOT_2_4 0x93ea7e11
#define SEGABOOT_2_4_SYM 0x3cc635ee
#define SEGABOOT_2_6 0x0030
#define SEGA_RACE_TV 0xfb096f81
#define THE_HOUSE_OF_THE_DEAD_4_REVA 0xbc0c9ffa
#define THE_HOUSE_OF_THE_DEAD_4_REVA_TEST 0x7235bda8
#define THE_HOUSE_OF_THE_DEAD_4_REVC 0x5df569f5
#define THE_HOUSE_OF_THE_DEAD_4_REVC_TEST 0xDDECE1E9
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL 0x12266f81
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST 0x83ba3b45
#define THE_HOUSE_OF_THE_DEAD_EX 0x85c0c22a
#define THE_HOUSE_OF_THE_DEAD_EX_TEST 0xb9a166bb
#define TOO_SPICY 0x4c768eb4
#define UNKNOWN 0xFFFFFFFF
#define VIRTUA_FIGHTER_5 0x0042
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN 0x48
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA 0xFBD3DCB6
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB 0x2B475B88
#define VIRTUA_FIGHTER_5_R 0x12D9D038
#define VIRTUA_FIGHTER_5_REVA 0x0046
#define VIRTUA_FIGHTER_5_REVB 0x0047
#define VIRTUA_FIGHTER_5_REVC 0x1bf1b627
#define VIRTUA_FIGHTER_5_REVE 0xC4B05D40
#define VIRTUA_FIGHTER_5_EXPORT 0x157B0576
#define VIRTUA_FIGHTER_5_R_REVD 0x0051
#define VIRTUA_TENNIS_3 0xc4b7e89
#define VIRTUA_TENNIS_3_TEST 0xffe3b0fd
#define AFTER_BURNER_CLIMAX 0xa3c246e2 // DVP-0009
#define AFTER_BURNER_CLIMAX_REVA 0xe657b1c0 // DVP-0009A
#define AFTER_BURNER_CLIMAX_REVB 0xdb9d8396 // DVP-0009B
#define AFTER_BURNER_CLIMAX_SDX 0xc042a0a2 // DVP-0018
#define AFTER_BURNER_CLIMAX_SDX_REVA 0xcb768831 // DVP-0018A
#define AFTER_BURNER_CLIMAX_SE 0x86df4e64 // DVP-0031
#define AFTER_BURNER_CLIMAX_SE_REVA 0x684352f4 // DVP-0031A
#define GHOST_SQUAD_EVOLUTION 0x455edaec // DVP-0029A
#define HARLEY_DAVIDSON 0xb1dd1c12 // DVP-5007
#define HUMMER 0x4e6d5c64 // DVP-0057B
#define HUMMER_SDLX 0xf3778f44 // DVP-0057
#define HUMMER_EXTREME 0x7129c32b // DVP-0079
#define HUMMER_EXTREME_MDX 0xfeaf8484 // DVP-0084
#define INITIALD_4_REVA 0x361d1cbe // DVP-0019A
#define INITIALD_4_REVB 0x606914be // DVP-0019B
#define INITIALD_4_REVC 0x50f1c269 // DVP-0019C
#define INITIALD_4_REVD 0xba380f8a // DVP-0019D
#define INITIALD_4_REVG 0x6cb19701 // DVP-0019G
#define INITIALD_4_EXP_REVB 0xd0c64f3 // DVP-0030B
#define INITIALD_4_EXP_REVC 0x65ea22e3 // DVP-0030C
#define INITIALD_4_EXP_REVD 0x62cc73a9 // DVP-0030D
#define INITIALD_5_JAP_REVA 0xb3183112 // DVP-0070A
#define INITIALD_5_JAP_REVF 0xfc3dc85d // DVP-0070F
#define INITIALD_5_EXP_30 0x77c6b58b // DVP-0075 and DVP-0084????
#define INITIALD_5_EXP_40 0xd4910e75 // DVP-0084A
#define LETS_GO_JUNGLE 0xb1c8c901 // DVP-0011
#define LETS_GO_JUNGLE_REVA 0xc697c4fb // DVP-0011A
#define LETS_GO_JUNGLE_SPECIAL 0x240beedc // DVP-0036A
#define OUTRUN_2_SP_SDX 0x92c196d5 // DVP-0015
#define OUTRUN_2_SP_SDX_REVA 0x4debd5f0 // DVP-0015A
#define OUTRUN_2_SP_SDX_REVA_TEST 0x6b2d5c46 // DVP-0015A
#define OUTRUN_2_SP_SDX_TEST 0xf1c89eae // DVP-0015
#define PRIMEVAL_HUNT 0x6868215c // DVP-0048A
#define RAMBO 0x48f49dd // DVP-0069
#define RAMBO_CHINA 0x0025 // DVP-????
#define R_TUNED 0xa68d053d // DVP-0060
#define SEGABOOT 0x0027 // DVP-????
#define SEGABOOT_2_4 0x38d56318 // DVP-????
#define SEGABOOT_2_4_SYM 0xa518b18b // DVP-????
#define SEGABOOT_2_6 0x0030 // DVP-????
#define SEGA_RACE_TV 0xb30ab16a // DVP-0044
#define THE_HOUSE_OF_THE_DEAD_4_REVA 0x226281ad // DVP-0003A
#define THE_HOUSE_OF_THE_DEAD_4_REVA_TEST 0x1d1160aa // DVP-0003A
#define THE_HOUSE_OF_THE_DEAD_4_REVB 0xad652b5 // DVP-0003B
#define THE_HOUSE_OF_THE_DEAD_4_REVB_TEST 0xbb24fef8 // DVP-0003B
#define THE_HOUSE_OF_THE_DEAD_4_REVC 0xe213414d // DVP-0003C
#define THE_HOUSE_OF_THE_DEAD_4_REVC_TEST 0x6210582b // DVP-0003C
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL 0x8a7c4ac7 // DVP-0010
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST 0xb896a44a // DVP-0010
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB 0x7d6ab3e3 // DVP-0010B
#define THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB_TEST 0xae47a9fc // DVP-0010B
#define THE_HOUSE_OF_THE_DEAD_EX 0x20115a92 // DVP-0063
#define THE_HOUSE_OF_THE_DEAD_EX_TEST 0xd58a0053 // DVP-0063
#define TOO_SPICY 0x46bb306e // DVP-0027A
#define TOO_SPICY_TEST 0x6510b2e6 // DVP-0027A
#define UNKNOWN 0xFFFFFFFF // ????????
#define VIRTUA_FIGHTER_5 0x71722584 // DVP-0008
#define VIRTUA_FIGHTER_5_REVA 0x9745abb6 // DVP-0008A
#define VIRTUA_FIGHTER_5_REVB 0x8953bd52 // DVP-0008B
#define VIRTUA_FIGHTER_5_REVE 0x4c2edbf6 // DVP-0008E
#define VIRTUA_FIGHTER_5_EXPORT 0xec474630 // DVP-0043
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN 0x48 // DVP-5019 or does not exist
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA 0xbae2be62 // DVP-5019A
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB 0x7cee1d81 // DVP-5020
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000 0x34c0d02 // DVP-5020 ver 6.00 (Weird public version)
#define VIRTUA_FIGHTER_5_R 0x79db39d // DVP-5004
#define VIRTUA_FIGHTER_5_R_REVD 0x443b6d07 // DVP-5004D
#define VIRTUA_TENNIS_3 0x7a021b5 // DVP-0005
#define VIRTUA_TENNIS_3_TEST 0x3bfbd11e // DVP-0005
#define VIRTUA_TENNIS_3_REVA 0xa9a10e32 // DVP-0005A
#define VIRTUA_TENNIS_3_REVA_TEST 0xdbcf31c1 // DVP-0005A
#define VIRTUA_TENNIS_3_REVB 0x67776c01 // DVP-0005B
#define VIRTUA_TENNIS_3_REVB_TEST 0xc689beeb // DVP-0005B
#define VIRTUA_TENNIS_3_REVC 0x55345ed0 // DVP-0005C
#define VIRTUA_TENNIS_3_REVC_TEST 0xdd7c4fea // DVP-0005C
typedef enum
{
YELLOW,
RED
YELLOW,
RED
} Colour;
typedef enum
{
WORKING,
NOT_WORKING
WORKING,
NOT_WORKING
} GameStatus;
typedef enum
{
JP,
US,
EX
JP,
US,
EX
} GameRegion;
typedef enum
{
SHOOTING,
DRIVING,
FIGHTING
SHOOTING,
DRIVING,
HARLEY,
FIGHTING,
ABC
} GameType;
typedef enum
{
AUTO_DETECT_GPU,
NVIDIA_GPU,
AMD_GPU,
ATI_GPU,
INTEL_GPU,
UNKNOWN_GPU,
ERROR_GPU
} GpuType;
typedef struct
{
unsigned int service;
unsigned int start;
unsigned int coin;
unsigned int up;
unsigned int down;
unsigned int left;
unsigned int right;
unsigned int button1;
unsigned int button2;
unsigned int button3;
unsigned int button4;
unsigned int service;
unsigned int start;
unsigned int coin;
unsigned int up;
unsigned int down;
unsigned int left;
unsigned int right;
unsigned int button1;
unsigned int button2;
unsigned int button3;
unsigned int button4;
unsigned int button5;
unsigned int button6;
unsigned int button7;
unsigned int button8;
} PlayerKeyMapping;
typedef struct
{
unsigned int test;
PlayerKeyMapping player1;
PlayerKeyMapping player2;
unsigned int test;
PlayerKeyMapping player1;
PlayerKeyMapping player2;
} KeyMapping;
typedef enum
{
SEGA_TYPE_1,
SEGA_TYPE_3
} JVSIOType;
typedef struct {
// Test button
char test[INPUT_STRING_LENGTH];
// Player 1 controls
char player1_button_start[INPUT_STRING_LENGTH];
char player1_button_service[INPUT_STRING_LENGTH];
char player1_button_up[INPUT_STRING_LENGTH];
char player1_button_down[INPUT_STRING_LENGTH];
char player1_button_left[INPUT_STRING_LENGTH];
char player1_button_right[INPUT_STRING_LENGTH];
char player1_button_1[INPUT_STRING_LENGTH];
char player1_button_2[INPUT_STRING_LENGTH];
char player1_button_3[INPUT_STRING_LENGTH];
char player1_button_4[INPUT_STRING_LENGTH];
char player1_button_5[INPUT_STRING_LENGTH];
char player1_button_6[INPUT_STRING_LENGTH];
char player1_button_7[INPUT_STRING_LENGTH];
char player1_button_8[INPUT_STRING_LENGTH];
char player1_button_9[INPUT_STRING_LENGTH];
char player1_button_10[INPUT_STRING_LENGTH];
// Player 2 controls
char player2_button_start[INPUT_STRING_LENGTH];
char player2_button_service[INPUT_STRING_LENGTH];
char player2_button_up[INPUT_STRING_LENGTH];
char player2_button_down[INPUT_STRING_LENGTH];
char player2_button_left[INPUT_STRING_LENGTH];
char player2_button_right[INPUT_STRING_LENGTH];
char player2_button_1[INPUT_STRING_LENGTH];
char player2_button_2[INPUT_STRING_LENGTH];
char player2_button_3[INPUT_STRING_LENGTH];
char player2_button_4[INPUT_STRING_LENGTH];
char player2_button_5[INPUT_STRING_LENGTH];
char player2_button_6[INPUT_STRING_LENGTH];
char player2_button_7[INPUT_STRING_LENGTH];
char player2_button_8[INPUT_STRING_LENGTH];
char player2_button_9[INPUT_STRING_LENGTH];
char player2_button_10[INPUT_STRING_LENGTH];
// Analogue inputs
char analogue_1[INPUT_STRING_LENGTH];
char analogue_2[INPUT_STRING_LENGTH];
char analogue_3[INPUT_STRING_LENGTH];
char analogue_4[INPUT_STRING_LENGTH];
char analogue_5[INPUT_STRING_LENGTH];
char analogue_6[INPUT_STRING_LENGTH];
char analogue_7[INPUT_STRING_LENGTH];
char analogue_8[INPUT_STRING_LENGTH];
} ArcadeInputs;
typedef struct
{
int emulateRideboard;
int emulateDriveboard;
int emulateMotionboard;
int emulateJVS;
int fullscreen;
char eepromPath[MAX_PATH_LENGTH];
char sramPath[MAX_PATH_LENGTH];
char jvsPath[MAX_PATH_LENGTH];
char serial1Path[MAX_PATH_LENGTH];
char serial2Path[MAX_PATH_LENGTH];
int width;
int height;
Colour lindberghColour;
GameStatus gameStatus;
GameType gameType;
KeyMapping keymap;
uint32_t crc32;
GameRegion region;
int freeplay;
int showDebugMessages;
char *gameID;
char *gameTitle;
char *gameDVP;
int jvsAnalogueInBits;
int emulateRideboard;
int emulateDriveboard;
int emulateMotionboard;
int emulateJVS;
int fullscreen;
char eepromPath[MAX_PATH_LENGTH];
char sramPath[MAX_PATH_LENGTH];
char jvsPath[MAX_PATH_LENGTH];
char serial1Path[MAX_PATH_LENGTH];
char serial2Path[MAX_PATH_LENGTH];
int width;
int height;
Colour lindberghColour;
GameStatus gameStatus;
GameType gameType;
KeyMapping keymap;
uint32_t crc32;
GameRegion region;
int freeplay;
int showDebugMessages;
char *gameID;
char *gameTitle;
char *gameDVP;
GpuType GPUVendor;
char *GPUVendorString;
JVSIOType jvsIOType;
int outrunLensGlareEnabled;
int hummerFlickerFix;
int keepAspectRatio;
int fpsLimiter;
int fpsTarget;
int lgjRenderWithMesa;
int noSDL;
int phMode;
ArcadeInputs arcadeInputs;
int inputMode; // 0 = both, 1 = SDL/X11 only, 2 = EVDEV only
} EmulatorConfig;
KeyMapping getDefaultKeymap();
@ -139,3 +251,5 @@ EmulatorConfig *getConfig();
char *getGameName();
char *getDVPName();
char *getGameID();
#endif

206
src/lindbergh/config_file.c Normal file
View File

@ -0,0 +1,206 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CONFIG_TEMP_FILE_NAME ".lindbergh.conf.tmp"
#include "config_file.h"
char *getConfigErrorString(ConfigStatus status)
{
switch (status)
{
case CONFIG_STATUS_COMMAND_NOT_FOUND:
return "The key you looked for could not be found";
case CONFIG_STATUS_FAILURE:
return "There was a generic failure";
case CONFIG_STATUS_SUCCESS:
return "The operation was successful";
case CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS:
return "The config file did not have enough arguments to complete your request";
case CONFIG_STATUS_CANNOT_OPEN_FILE:
return "The config file could not be opened";
default:
return "This config status enum doesn't have an error string associated.";
}
return "This config status enum doesn't have an error string associated.";
}
static char *getNextToken(char *buffer, char *seperator, char **saveptr)
{
char *token = strtok_r(buffer, seperator, saveptr);
if (token == NULL)
return NULL;
for (int i = 0; i < (int)strlen(token); i++)
{
if ((token[i] == '\n') || (token[i] == '\r'))
{
token[i] = 0;
}
}
return token;
}
ConfigStatus processConfig(Config *config, char *path)
{
config->path = path;
config->file = fopen(config->path, "r");
config->configPairIndex = 0;
if (config->file == NULL)
{
return CONFIG_STATUS_CANNOT_OPEN_FILE;
}
char buffer[CONFIG_MAX_LINE_LENGTH];
char *saveptr = NULL;
while (fgets(buffer, CONFIG_MAX_LINE_LENGTH, config->file))
{
// Ignore any lines that start with a comment
if (buffer[0] == '#' || buffer[0] == 0 || buffer[0] == ' ' || buffer[0] == '\r' || buffer[0] == '\n')
continue;
ConfigPair *configPair = &config->configPairs[config->configPairIndex];
strcpy(configPair->command, getNextToken(buffer, " ", &saveptr));
configPair->argumentIndex = 0;
char *argument = getNextToken(NULL, " ", &saveptr);
while (argument != NULL && argument[0] != 0)
{
strcpy(configPair->argument[configPair->argumentIndex++], argument);
argument = getNextToken(NULL, " ", &saveptr);
}
config->configPairIndex++;
}
fclose(config->file);
return CONFIG_STATUS_SUCCESS;
}
ConfigStatus getConfigArgumentString(Config *config, char *key, int n, char *value)
{
for (int i = 0; i < config->configPairIndex; i++)
{
if (strcmp(config->configPairs[i].command, key) == 0)
{
if (n >= config->configPairs[i].argumentIndex)
return CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS;
strcpy(value, config->configPairs[i].argument[n]);
return CONFIG_STATUS_SUCCESS;
}
}
return CONFIG_STATUS_COMMAND_NOT_FOUND;
}
ConfigStatus getConfigArgumentInt(Config *config, char *key, int n, int *value)
{
for (int i = 0; i < config->configPairIndex; i++)
{
if (strcmp(config->configPairs[i].command, key) == 0)
{
if (n >= config->configPairs[i].argumentIndex)
return CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS;
*value = atoi(config->configPairs[i].argument[i]);
return CONFIG_STATUS_SUCCESS;
}
}
return CONFIG_STATUS_COMMAND_NOT_FOUND;
}
ConfigStatus getConfigString(Config *config, char *key, char *value)
{
return getConfigArgumentString(config, key, 0, value);
}
ConfigStatus getConfigInt(Config *config, char *key, int *value)
{
return getConfigArgumentInt(config, key, 0, value);
}
ConfigStatus writeConfigString(Config *config, char *key, char *value)
{
config->file = fopen(config->path, "r");
if (config->file == NULL)
{
return CONFIG_STATUS_FAILURE;
}
FILE *tempFile = fopen(CONFIG_TEMP_FILE_NAME, "w");
if (tempFile == NULL)
{
return CONFIG_STATUS_FAILURE;
}
char buffer[CONFIG_MAX_LINE_LENGTH];
char *saveptr = NULL;
char inspectionBuffer[CONFIG_MAX_LINE_LENGTH];
char writeBuffer[CONFIG_MAX_LINE_LENGTH];
strcpy(writeBuffer, key);
strcat(writeBuffer, " ");
strcat(writeBuffer, value);
strcat(writeBuffer, "\n");
int lineWasReplaced = 0;
while (fgets(buffer, CONFIG_MAX_LINE_LENGTH, config->file))
{
strcpy(inspectionBuffer, buffer);
char *token = getNextToken(inspectionBuffer, " ", &saveptr);
if (strcmp(token, key) == 0)
{
lineWasReplaced = 1;
// If there is no value just delete the line
if (strcmp(value, "") == 0)
continue;
fputs(writeBuffer, tempFile);
continue;
}
fputs(buffer, tempFile);
}
// If the file doesn't end with a new line, write one.
if (buffer[strlen(buffer) - 1] != '\n')
fputs("\n", tempFile);
// If no line was replaced add it in at the end
if (!lineWasReplaced)
fputs(writeBuffer, tempFile);
fclose(config->file);
fclose(tempFile);
// Now re-write the old file with the new temp file name
remove(config->path);
rename(CONFIG_TEMP_FILE_NAME, config->path);
return processConfig(config, config->path);
}
ConfigStatus writeConfigInt(Config *config, char *key, int value)
{
char stringValue[CONFIG_MAX_LINE_LENGTH];
sprintf(stringValue, "%d", value);
return writeConfigString(config, key, stringValue);
}
ConfigStatus deleteConfig(Config *config, char *key)
{
return writeConfigString(config, key, "");
}

View File

@ -0,0 +1,45 @@
#include <stdlib.h>
#define CONFIG_MAX_LINE_LENGTH 2048
#define MAX_ARGUMENT_AMOUNT 4
#define MAX_CONFIG_LINES 100
typedef enum
{
CONFIG_STATUS_SUCCESS,
CONFIG_STATUS_FAILURE,
CONFIG_STATUS_COMMAND_NOT_FOUND,
CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS,
CONFIG_STATUS_CANNOT_OPEN_FILE
} ConfigStatus;
typedef struct {
char command[CONFIG_MAX_LINE_LENGTH];
char argument[MAX_ARGUMENT_AMOUNT][CONFIG_MAX_LINE_LENGTH];
int argumentIndex;
} ConfigPair;
typedef struct
{
FILE *file;
char* path;
int configPairIndex;
ConfigPair configPairs[MAX_CONFIG_LINES];
} Config;
char* getConfigErrorString(ConfigStatus status);
ConfigStatus processConfig(Config *config, char *path);
ConfigStatus getConfigString(Config *config, char* key, char* value);
ConfigStatus getConfigArgumentString(Config *config, char* key, int n, char* value);
ConfigStatus getConfigInt(Config *config, char* key, int* value);
ConfigStatus getConfigArgumentInt(Config *config, char* key, int n, int* value);
ConfigStatus writeConfigString(Config *config, char* key, char* value);
ConfigStatus writeConfigInt(Config *config, char* key, int value);
ConfigStatus deleteConfig(Config *config, char* key);

View File

@ -1,10 +1,10 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "config.h"
#include "eeprom.h"
#include "eeprom_settings.h"
#include "config.h"
#define I2C_SMBUS_BLOCK_MAX 32
#define I2C_GET_FUNCTIONS 0x705
@ -15,8 +15,7 @@
#define I2C_SEEK 2
#define I2C_WRITE 3
union i2c_smbus_data
{
union i2c_smbus_data {
uint8_t byte;
uint16_t word;
uint8_t block[I2C_SMBUS_BLOCK_MAX + 2];
@ -68,7 +67,9 @@ int initEeprom()
setFreeplay(eeprom, getConfig()->freeplay);
}
if ((getConfig()->crc32 == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_EX) || (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL))
if ((getConfig()->crc32 == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_EX) ||
(getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) ||
(getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB))
{
if (fixCreditSection(eeprom) != 0)
{
@ -78,6 +79,17 @@ int initEeprom()
}
}
if (getConfig()->crc32 == HUMMER || getConfig()->crc32 == HUMMER_SDLX || getConfig()->crc32 == HUMMER_EXTREME ||
getConfig()->crc32 == HUMMER_EXTREME_MDX)
{
if (fixCoinAssignmentsHummer(eeprom) != 0)
{
printf("Error initializing eeprom settings.");
fclose(eeprom);
return 1;
}
}
fseek(eeprom, 0, SEEK_SET);
return 0;
@ -95,7 +107,8 @@ int eepromIoctl(int fd, unsigned int request, void *data)
functions[0] = 0x20000 | 0x40000 | 0x100000 | 0x400000 | 0x8000000;
// The following is taken from the eeprom init sequence in The House Of The Dead 4 so let's add em on!
functions[0] = functions[0] | 0x20000 | 0x40000 | 0x80000 | 0x100000 | 0x200000 | 0x400000 | 0x1000000 | 0x2000000;
functions[0] =
functions[0] | 0x20000 | 0x40000 | 0x80000 | 0x100000 | 0x200000 | 0x400000 | 0x1000000 | 0x2000000;
}
break;

View File

@ -213,6 +213,19 @@ int fixCreditSection(FILE *eeprom)
return 0;
}
int fixCoinAssignmentsHummer(FILE *eeprom)
{
eepromBuffer[eepromOffsetTable[CREDIT].offset + 35] = 0;
eepromBuffer[eepromOffsetTable[CREDIT].offset + 36] = 0;
addCRCtoBuffer(CREDIT);
if (writeSectiontoFile(eeprom, CREDIT) != 0)
{
printf("Error writing to eeprom.");
return 1;
}
return 0;
}
int eepromSettingsInit( FILE *eeprom)
{
build_crc32_table();

View File

@ -4,3 +4,4 @@ int getFreeplay();
int setRegion(FILE *eeprom, int region);
int setFreeplay(FILE *eeprom, int freeplay);
int fixCreditSection(FILE *eeprom);
int fixCoinAssignmentsHummer(FILE *eeprom);

1339
src/lindbergh/evdevinput.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
#include <pthread.h>
#include <linux/input-event-codes.h>
#define SIZE 1024
#define CONTROLLER_THREAD_MAX 256
typedef struct
{
char *arcade[SIZE];
char *pc[SIZE];
int count;
} ControllerMapping;
typedef struct
{
char name[SIZE];
int player;
int channel;
int enabled;
char minName[SIZE];
int minPlayer;
int minChannel;
int minEnabled;
char maxName[SIZE];
int maxPlayer;
int maxChannel;
int maxEnabled;
int isAnalogue;
} ArcadeInput;
typedef enum
{
CONTROLLER_STATUS_SUCCESS = 0,
CONTROLLER_STATUS_ERROR = 1
} ControllerStatus;
typedef enum {
NO_SPECIAL_FUNCTION = 0,
ANALOGUE_TO_DIGITAL_MAX,
ANALOGUE_TO_DIGITAL_MIN,
DIGITAL_TO_ANALOGUE
} SpecialFunction;
typedef struct
{
char inputName[SIZE];
int evType;
int evCode;
SpecialFunction specialFunction;
} ControllerInput;
typedef struct
{
char name[SIZE];
char path[SIZE];
char physicalLocation[SIZE];
int absMax[ABS_MAX];
int absMin[ABS_MAX];
ControllerInput inputs[SIZE];
int inputCount;
ArcadeInput keyTriggers[KEY_MAX];
ArcadeInput absTriggers[ABS_MAX];
int enabled;
int inUse;
} Controller;
typedef struct
{
Controller *controller;
int count;
pthread_t thread[CONTROLLER_THREAD_MAX];
int threadIndex;
int threadsRunning;
} Controllers;
ControllerStatus initControllers(Controllers *controllers);
ControllerStatus stopControllers(Controllers *controllers);

View File

@ -0,0 +1,64 @@
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include "fps_limiter.h"
fps_limit fpsLimit;
double lastTime = 0.0;
int frameCount = 0;
double fps = 0.0;
double getTimeInMilliseconds()
{
struct timeval time;
gettimeofday(&time, NULL);
return (time.tv_sec * 1000.0) + (time.tv_usec / 1000.0);
}
double getTimeInSeconds()
{
struct timeval time;
gettimeofday(&time, NULL);
return (double)time.tv_sec + (double)time.tv_usec / 1000000.0;
}
double calculateFps()
{
double currentTime = getTimeInSeconds();
double deltaTime = currentTime - lastTime;
frameCount++;
if (deltaTime >= 1.0)
{
fps = frameCount / deltaTime;
frameCount = 0;
lastTime = currentTime;
}
return fps;
}
long Clock_now()
{
struct timeval time_now;
gettimeofday(&time_now, NULL);
return time_now.tv_sec * 1000000L + time_now.tv_usec;
}
void FpsLimiter(fps_limit *stats)
{
stats->sleepTime = stats->targetFrameTime - (stats->frameStart - stats->frameEnd);
if (stats->sleepTime > stats->frameOverhead)
{
long adjustedSleep = stats->sleepTime - stats->frameOverhead;
usleep(adjustedSleep);
stats->frameOverhead = (Clock_now() - stats->frameStart) - adjustedSleep;
if (stats->frameOverhead > stats->targetFrameTime / 2)
{
stats->frameOverhead = 0;
}
}
}

View File

@ -0,0 +1,17 @@
#ifndef FPS_LIMITER_H
#define FPS_LIMITER_H
typedef struct
{
long targetFrameTime; // Target frame time in microseconds
long frameStart; // Start time of the frame
long frameEnd; // End time of the frame
long sleepTime; // Sleep time to maintain the frame rate
long frameOverhead; // Overhead time in the frame
} fps_limit;
long Clock_now();
void FpsLimiter(fps_limit *stats);
double calculateFps();
#endif

481
src/lindbergh/gluthooks.c Normal file
View File

@ -0,0 +1,481 @@
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <GL/freeglut.h>
#include <GL/freeglut_std.h>
#include <GL/glx.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <dlfcn.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "config.h"
#include "fps_limiter.h"
#include "sdlcalls.h"
extern SDL_Window *SDLwindow;
extern char SDLgameTitle[];
extern fps_limit fpsLimit;
void *displayFunc = NULL;
void *reshapeFunc = NULL;
void *visibilityFunc = NULL;
void *idleFunc = NULL;
void FGAPIENTRY glutInit(int *argcp, char **argv)
{
if (*argcp > 1 && getConfig()->crc32 == SEGA_RACE_TV)
{
for (int x = 0; x < *argcp; x++)
{
if (strcmp(argv[x], "-t") == 0)
{
EmulatorConfig *config = getConfig();
config->noSDL = 0;
printf("Forced to use SDL to make Test mode render fine.");
}
}
}
glutInitSDL(argcp, argv);
}
void FGAPIENTRY glutMainLoop(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMainLoop)(void) = dlsym(RTLD_NEXT, "glutMainLoop");
_glutMainLoop();
return;
}
bool quit = false;
while (!quit)
{
pollEvents();
int w, h;
SDL_GetWindowSize(SDLwindow, &w, &h);
if (displayFunc != NULL)
(((void *(*)(void))displayFunc)());
if (reshapeFunc != NULL)
(((void *(*)(int, int))reshapeFunc)(w, h));
if (visibilityFunc != NULL)
(((void *(*)(int))visibilityFunc)(1));
if (idleFunc != NULL)
(((void *(*)(void))idleFunc)());
}
SDL_DestroyWindow(SDLwindow);
SDL_Quit();
}
void FGAPIENTRY glutMainLoopEvent(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMainLoopEvent)(void) = dlsym(RTLD_NEXT, "glutMainLoopEvent");
_glutMainLoopEvent();
}
return;
}
void FGAPIENTRY glutSwapBuffers(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSwapBuffers)(void) = dlsym(RTLD_NEXT, "glutSwapBuffers");
_glutSwapBuffers();
return;
}
int gId = getConfig()->crc32;
if (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST ||
gId == OUTRUN_2_SP_SDX_TEST)
{
pollEvents();
}
SDL_GL_SwapWindow(SDLwindow);
if (getConfig()->fpsLimiter)
{
fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit);
fpsLimit.frameEnd = Clock_now();
}
char windowTitle[512];
sprintf(windowTitle, "%s - FPS: %.2f", SDLgameTitle, calculateFps());
SDL_SetWindowTitle(SDLwindow, windowTitle);
}
int FGAPIENTRY glutGet(GLenum type)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutGet)(GLenum type) = dlsym(RTLD_NEXT, "glutGet");
return _glutGet(type);
}
if (type == 0x66)
return getConfig()->width;
if (type == 0x67)
return getConfig()->height;
return 0;
}
void FGAPIENTRY glutInitWindowSize(int width, int height)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitWindowSize)(int width, int height) = dlsym(RTLD_NEXT, "glutInitWindowSize");
_glutInitWindowSize(width, height);
return;
}
SDL_SetWindowSize(SDLwindow, getConfig()->width, getConfig()->height);
}
void FGAPIENTRY glutInitWindowPosition(int x, int y)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitWindowPosition)(int width, int height) = dlsym(RTLD_NEXT, "glutInitWindowPosition");
_glutInitWindowPosition(x, y);
return;
}
SDL_SetWindowPosition(SDLwindow, x, y);
}
int FGAPIENTRY glutExtensionSupported(const char *extension)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutExtensionSupported)(const char *extension) = dlsym(RTLD_NEXT, "glutExtensionSupported");
return _glutExtensionSupported(extension);
}
return SDL_GL_ExtensionSupported(extension);
}
void FGAPIENTRY glutSetCursor(int glutCursor)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSetCursor)(int glutCursor) = dlsym(RTLD_NEXT, "glutSetCursor");
_glutSetCursor(glutCursor);
return;
}
SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
SDL_SetCursor(cursor);
}
void FGAPIENTRY glutDisplayFunc(void (*callback)(void))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutDisplayFunc)(void (*callback)(void)) = dlsym(RTLD_NEXT, "glutDisplayFunc");
_glutDisplayFunc(callback);
return;
}
displayFunc = callback;
}
void FGAPIENTRY glutReshapeFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutReshapeFunc)(void (*callback)(int, int)) = dlsym(RTLD_NEXT, "glutReshapeFunc");
_glutReshapeFunc(callback);
return;
}
reshapeFunc = callback;
}
void FGAPIENTRY glutVisibilityFunc(void (*callback)(int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutVisibilityFunc)(void (*callback)(int)) = dlsym(RTLD_NEXT, "glutVisibilityFunc");
_glutVisibilityFunc(callback);
return;
}
visibilityFunc = callback;
}
void FGAPIENTRY glutIdleFunc(void (*callback)(void))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutIdleFunc)(void (*callback)(void)) = dlsym(RTLD_NEXT, "glutIdleFunc");
_glutIdleFunc(callback);
return;
}
idleFunc = callback;
}
void FGAPIENTRY glutInitDisplayMode(unsigned int mode)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitDisplayMode)(unsigned int mode) = dlsym(RTLD_NEXT, "glutInitDisplayMode");
_glutInitDisplayMode(mode);
return;
}
return;
}
void FGAPIENTRY glutGameModeString(const char *string)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutGameModeString)(const char *string) = dlsym(RTLD_NEXT, "glutGameModeString");
_glutGameModeString(string);
return;
}
return;
}
int FGAPIENTRY glutEnterGameMode(void)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutEnterGameMode)(void) = dlsym(RTLD_NEXT, "glutEnterGameMode");
char gameTitle[256] = {0};
strcat(gameTitle, getGameName());
glutCreateWindow(gameTitle);
return 1;
}
return 0;
}
int FGAPIENTRY glutCreateWindow(const char *title)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutCreateWindow)(const char *title) = dlsym(RTLD_NEXT, "glutCreateWindow");
return _glutCreateWindow(title);
}
return 1;
}
void FGAPIENTRY glutJoystickFunc(void (*callback)(unsigned int, int, int, int), int pollInterval)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutJoystickFunc)(void (*callback)(unsigned int, int, int, int), int pollInterval) =
dlsym(RTLD_NEXT, "glutJoystickFunc");
_glutJoystickFunc(callback, pollInterval);
return;
}
return;
}
void FGAPIENTRY glutPostRedisplay(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutPostRedisplay)(void) = dlsym(RTLD_NEXT, "glutPostRedisplay");
_glutPostRedisplay();
return;
}
return;
}
void FGAPIENTRY glutKeyboardFunc(void (*callback)(unsigned char, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutKeyboardFunc)(void (*callback)(unsigned char, int, int)) =
dlsym(RTLD_NEXT, "glutKeyboardFunc");
_glutKeyboardFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutKeyboardUpFunc(void (*callback)(unsigned char, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutKeyboardUpFunc)(void (*callback)(unsigned char, int, int)) =
dlsym(RTLD_NEXT, "glutKeyboardUpFunc");
_glutKeyboardUpFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutMouseFunc(void (*callback)(int, int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMouseFunc)(void (*callback)(int, int, int, int)) = dlsym(RTLD_NEXT, "glutMouseFunc");
_glutMouseFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutMotionFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMotionFunc)(void (*callback)(int, int)) = dlsym(RTLD_NEXT, "glutMotionFunc");
_glutMotionFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutSpecialFunc(void (*callback)(int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSpecialFunc)(void (*callback)(int, int, int)) = dlsym(RTLD_NEXT, "glutSpecialFunc");
_glutSpecialFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutSpecialUpFunc(void (*callback)(int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSpecialUpFunc)(void (*callback)(int, int, int)) = dlsym(RTLD_NEXT, "glutSpecialUpFunc");
_glutSpecialUpFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutPassiveMotionFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutPassiveMotionFunc)(void (*callback)(int, int)) =
dlsym(RTLD_NEXT, "glutPassiveMotionFunc");
_glutPassiveMotionFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutEntryFunc(void (*callback)(int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutEntryFunc)(void (*callback)(int)) = dlsym(RTLD_NEXT, "glutEntryFunc");
_glutEntryFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutLeaveGameMode()
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutLeaveGameMode)() = dlsym(RTLD_NEXT, "glutLeaveGameMode");
_glutLeaveGameMode();
return;
}
return;
}
void FGAPIENTRY glutSolidTeapot(double size)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidTeapot)(double size) = dlsym(RTLD_NEXT, "glutSolidTeapot");
_glutSolidTeapot(size);
return;
}
return;
}
void FGAPIENTRY glutWireTeapot(double size)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireTeapot)(double size) = dlsym(RTLD_NEXT, "glutWireTeapot");
_glutWireTeapot(size);
return;
}
return;
}
void FGAPIENTRY glutSolidSphere(double radius, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidSphere)(double radius, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutSolidSphere");
_glutSolidSphere(radius, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireSphere(double radius, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireSphere)(double radius, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutWireSphere");
_glutWireSphere(radius, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireCone(double base, double height, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireCone)(double base, double height, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutWireCone");
_glutWireCone(base, height, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutSolidCone(double base, double height, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidCone)(double base, double height, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutSolidCone");
_glutSolidCone(base, height, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireCube(double dSize)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireCube)(double dSize) = dlsym(RTLD_NEXT, "glutWireCube");
_glutWireCube(dSize);
return;
}
return;
}
void FGAPIENTRY glutSolidCube(double dSize)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidCube)(double dSize) = dlsym(RTLD_NEXT, "glutSolidCube");
_glutSolidCube(dSize);
return;
}
return;
}

29
src/lindbergh/gluthooks.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef GLUTHOOKS_H
#define GLUTHOOKS_H
#include <GL/glx.h>
int myCreateWindow(int *param1);
void hod4glXSwapBuffers(Display *dpy, GLXDrawable drawable);
#endif
// #include <GL/freeglut.h>
// /* The bitmap font structure taken from freeglut*/
// typedef struct tagSFG_Font SFG_Font;
// struct tagSFG_Font
// {
// char *Name; /* The source font name */
// int Quantity; /* Number of chars in font */
// int Height; /* Height of the characters */
// const GLubyte **Characters; /* The characters mapping */
// float xorig, yorig; /* Relative origin of the character */
// };
// extern SFG_Font fgFontFixed8x13;
// extern SFG_Font fgFontFixed9x15;
// extern SFG_Font fgFontHelvetica10;
// extern SFG_Font fgFontHelvetica12;
// extern SFG_Font fgFontHelvetica18;
// extern SFG_Font fgFontTimesRoman10;
// extern SFG_Font fgFontTimesRoman24;

355
src/lindbergh/glxhooks.c Normal file
View File

@ -0,0 +1,355 @@
#define GL_GLEXT_PROTOTYPES
#ifndef __i386__
#define __i386__
#include <GL/gl.h>
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_video.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdint.h>
#include <time.h>
#endif
#undef __x86_64__
#include <GL/glx.h>
#include <GL/glxext.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <SDL2/SDL.h>
#include <sys/time.h>
#include "fps_limiter.h"
#include "sdlcalls.h"
#include "patch.h"
#include "config.h"
bool sdlGame = false;
extern SDL_Window *SDLwindow;
extern SDL_GLContext SDLcontext;
extern char SDLgameTitle[];
extern fps_limit fpsLimit;
extern Window win;
void glXToSDLSwapBuffers(Display *dpy, GLXDrawable drawable)
{
pollEvents();
SDL_GL_SwapWindow(SDLwindow);
if (getConfig()->fpsLimiter)
{
fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit);
fpsLimit.frameEnd = Clock_now();
}
char windowTitle[512];
sprintf(windowTitle, "%s - FPS: %.2f", SDLgameTitle, calculateFps());
SDL_SetWindowTitle(SDLwindow, windowTitle);
}
int glxSDLmyCreateWindow(int *param1)
{
glutInitSDL(0, 0);
char *buf = malloc(512);
memset(buf, '\0', 512);
// param1[0x17] = (intptr_t)(void *)buf; // window;
sdlGame = true;
return 1;
}
XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
{
XVisualInfo *(*_glXChooseVisual)(Display *dpy, int screen, int *attribList) = dlsym(RTLD_NEXT, "glXChooseVisual");
if (sdlGame)
return 0;
return _glXChooseVisual(dpy, screen, attribList);
}
void GLAPIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
if (id == 1099)
return;
// Print the debug message details
printf("OpenGL Debug Message:\n");
printf("Source: 0x%x\n", source);
printf("Type: 0x%x\n", type);
printf("ID: %u\n", id);
printf("Severity: 0x%x\n", severity);
printf("Message: %s\n", message);
// You can filter based on severity or other attributes if needed
if (severity == GL_DEBUG_SEVERITY_HIGH)
{
printf("This is a high severity error!\n");
}
}
void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
{
void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable) = dlsym(RTLD_NEXT, "glXSwapBuffers");
int gId = getConfig()->crc32;
if (getConfig()->noSDL && (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA ||
gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_TEST))
{
XEvent event;
while (XPending(dpy))
{
XNextEvent(dpy, &event);
}
}
_glXSwapBuffers(dpy, drawable);
if (getConfig()->fpsLimiter)
{
fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit);
fpsLimit.frameEnd = Clock_now();
}
XStoreName(dpy, win, "");
}
GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct)
{
GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) =
dlsym(RTLD_NEXT, "glXCreateContext");
if (sdlGame)
{
return SDLcontext;
}
GLXContext ctx = _glXCreateContext(dpy, vis, shareList, direct);
if (getConfig()->showDebugMessages)
{
// Enable OpenGL debug output
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // Make the callback synchronous
glDebugMessageCallback(openglDebugCallback, NULL);
}
return ctx;
}
GLXContext glXGetCurrentContext()
{
GLXContext (*_glXGetCurrentContext)() = dlsym(RTLD_NEXT, "glXGetCurrentContext");
if (sdlGame)
return SDLcontext;
return _glXGetCurrentContext();
}
GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
{
GLXPbuffer (*_glXCreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attrib_list) =
dlsym(RTLD_NEXT, "glXCreatePbuffer");
if (sdlGame)
return 0;
return _glXCreatePbuffer(dpy, config, attrib_list);
}
void glXDestroyContext(Display *dpy, GLXContext ctx)
{
void (*_glXDestroyContext)(Display *dpy, GLXContext ctx) = dlsym(RTLD_NEXT, "glXDestroyContext");
if (sdlGame)
return;
_glXDestroyContext(dpy, ctx);
}
void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
{
void (*_glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf) = dlsym(RTLD_NEXT, "glXDestroyPbuffer");
if (sdlGame)
return;
_glXDestroyPbuffer(dpy, pbuf);
}
XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
{
XVisualInfo *(*_glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) =
dlsym(RTLD_NEXT, "glXGetVisualFromFBConfig");
if (sdlGame)
return 0;
return _glXGetVisualFromFBConfig(dpy, config);
}
Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
{
Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx) = dlsym(RTLD_NEXT, "glXMakeCurrent");
if (sdlGame)
{
SDL_GL_MakeCurrent(SDLwindow, SDLcontext);
return 1;
}
return _glXMakeCurrent(dpy, drawable, ctx);
}
Bool glXQueryExtension(Display *dpy, int *errorBase, int *eventBase)
{
Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase) = dlsym(RTLD_NEXT, "glXQueryExtension");
if (sdlGame)
return 0;
return _glXQueryExtension(dpy, errorBase, eventBase);
}
GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attrib_list, int *nelements)
{
GLXFBConfig *(*_glXChooseFBConfig)(Display *dpy, int screen, const int *attrib_list, int *nelements) =
dlsym(RTLD_NEXT, "glXChooseFBConfig");
int gId = getConfig()->crc32;
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) &&
((gId == THE_HOUSE_OF_THE_DEAD_4_REVA) || (gId == THE_HOUSE_OF_THE_DEAD_4_REVB) ||
(gId == THE_HOUSE_OF_THE_DEAD_4_REVC) || (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) ||
(gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) || (gId == THE_HOUSE_OF_THE_DEAD_EX) || (gId == TOO_SPICY)))
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemory((intptr_t)ptr, "01");
setVariable((intptr_t)ptr, GLX_DONT_CARE);
}
}
}
return _glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
{
GLXContext (*_glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list,
Bool direct) = dlsym(RTLD_NEXT, "glXCreateNewContext");
GLXContext ctx = _glXCreateNewContext(dpy, config, render_type, share_list, direct);
if (getConfig()->showDebugMessages)
{
// Enable OpenGL debug output
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(openglDebugCallback, NULL);
}
return ctx;
}
GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height,
int *attrib_list)
{
if (sdlGame)
return 0;
int pbufferAttribs[] = {GLX_PBUFFER_WIDTH,
width,
GLX_PBUFFER_HEIGHT,
height,
GLX_PRESERVED_CONTENTS,
true,
GLX_LARGEST_PBUFFER,
true,
None};
return glXCreatePbuffer(dpy, config, pbufferAttribs);
}
void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
if (sdlGame)
return;
glXDestroyPbuffer(dpy, pbuf);
}
GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
if (sdlGame)
return 0;
int gId = getConfig()->crc32;
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) &&
((gId == INITIALD_4_REVA) || (gId == INITIALD_4_REVB) || (gId == INITIALD_4_REVC) || (gId == INITIALD_4_REVD) ||
(gId == INITIALD_4_REVG) || (gId == INITIALD_4_EXP_REVB) || (gId == INITIALD_4_EXP_REVC) ||
gId == INITIALD_4_EXP_REVD))
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemory((intptr_t)ptr, "01");
}
}
}
return glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
if (sdlGame)
return 0;
return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list,
Bool direct)
{
if (sdlGame)
return 0;
return glXCreateNewContext(dpy, config, render_type, share_list, direct);
}
const char *glXGetClientString(Display *dpy, int name)
{
const char *(*_glXGetClientString)(Display *dpy, int name) = dlsym(RTLD_NEXT, "glXGetClientString");
if (sdlGame)
return "SDLGame";
return _glXGetClientString(dpy, name);
}
Display *glXGetCurrentDisplay(void)
{
Display *(*_glXGetCurrentDisplay)(void) = dlsym(RTLD_NEXT, "glXGetCurrentDisplay");
if (sdlGame)
return (Display *)SDLwindow;
return _glXGetCurrentDisplay();
}
const char *glXQueryExtensionsString(Display *dpy, int screen)
{
const char *(*_glXQueryExtensionsString)(Display *dpy, int screen) = dlsym(RTLD_NEXT, "glXQueryExtensionsString");
if (sdlGame)
return "";
return _glXQueryExtensionsString(dpy, screen);
}
const char *glXQueryServerString(Display *dpy, int screen, int name)
{
const char *(*_glXQueryServerString)(Display *dpy, int screen, int name) = dlsym(RTLD_NEXT, "glXQueryServerString");
if (sdlGame)
return "";
return _glXQueryServerString(dpy, screen, name);
}
int glXGetVideoSyncSGI(uint *count)
{
static unsigned int frameCount = 0;
*count = (frameCount++) / 2;
return 0;
}
int glXGetRefreshRateSGI(unsigned int *rate)
{
*rate = 60;
return 0;
}
int glXSwapIntervalSGI(int interval)
{
return 0;
}

4
src/lindbergh/glxhooks.h Normal file
View File

@ -0,0 +1,4 @@
#include <GL/glx.h>
void glXToSDLSwapBuffers(Display *dpy, GLXDrawable drawable);
int glxSDLmyCreateWindow(int *param1);

Some files were not shown because too many files have changed in this diff Show More