Compare commits

...

664 Commits

Author SHA1 Message Date
Sam Carlberg
77d6c11743 Invert right side motors in MecanumDrive sendable (#933)
This aligns with the current behavior of DifferentialDrive
Fixes shuffleboard#404
2018-02-09 08:30:12 -08:00
Tyler Veness
67f9c9a5b3 Fixed TimedRobot.java hanging if an exception was thrown (#926) 2018-02-04 22:38:19 -08:00
Thad House
f720cbb121 Switches CtreCanNode to use locking and std::chrono for time (#909) 2018-02-01 21:39:06 -08:00
Tyler Veness
64a7e57fe0 Added output normalization to DifferentialDrive::CurvatureDrive() (#924)
This normalizes within -1..1 to avoid clipping and maintain the ratio between
wheel speeds, since that ratio determines the center of rotation.

Fixes #923.
2018-02-01 21:17:04 -08:00
Tyler Veness
5ca00dddbe Added TimedRobot::GetPeriod() (#915)
Fixes #914.
2018-01-27 01:01:15 -08:00
Tyler Veness
120ceb3427 Fix channel reassignments for C++ Joystick twist and throttle axes (#903) 2018-01-26 17:26:10 -08:00
Thad House
5cbafc1382 Updates to image 17 (#913)
These should be binary compatible, so safe to use with image 16.
2018-01-26 17:21:13 -08:00
Thad House
39d1650d51 Fixes double to int to double cast in encoderJNI (#918)
Fixes #916
2018-01-26 17:20:20 -08:00
Thad House
02336fc478 Makes FMS data never be a null string. (#900)
Fixes #895
2018-01-19 23:49:34 -08:00
Thad House
c00848c060 Fixes indexed classed handle resource (#899)
Nothing in WPILib uses it, so it was not tested
2018-01-19 22:31:59 -08:00
Dustin Spicuzza
738a1c015c PIDController: setContinuous should only check input range if continuous is true (#896) 2018-01-19 22:31:08 -08:00
Thad House
48ae6c954a Publishes match specific data and other FMS info to NT (#874)
This is so products like SB can present the current setup.
2018-01-18 23:17:28 -08:00
Thad House
07f70cf784 Fixes control data packet delay (#875)
Because of an expected change in 2018 that didn't happen, we had a race
condition causing a 1 packet delay on all DS values. This fixes that.
2018-01-18 21:54:33 -08:00
sciencewhiz
e4e1eab413 Fix cancel of inner commands in ConditionalCommands (#858) 2018-01-18 20:04:33 -08:00
Nic Hodlofski
0e8ff4663d SpeedControllerGroup: Call set() from pidWrite()
This means pidWrite() now takes m_isInverted into account.
Fixes #887.
2018-01-18 20:03:13 -08:00
HeroCC
54a0a7654a Link to replacements for RobotDrive in JavaDocs (#879)
In smart IDEs, this will allow users to easily view source for these two classes by linking to it
2018-01-11 22:17:33 -08:00
Rohit Vighne
59f938b584 Invert when getting motor speed in SpeedControllerGroup (#886) 2018-01-11 22:16:42 -08:00
sciencewhiz
5513888457 Fix PIDController with Continous and no Input Range set. (#883) 2018-01-11 21:06:25 -08:00
Peter Johnson
02b6615042 RobotController: Make getBatteryVoltage() static. (#869) 2018-01-04 23:12:13 -06:00
Tyler Veness
1f4822f332 Replaced Talon motor controller in DifferentialDrive class docs with Spark (#868) 2018-01-03 20:27:34 -06:00
Peter Johnson
bb38ef5642 DifferentialDrive: Invert right motor in LiveWindow. (#867) 2018-01-02 21:15:15 -06:00
PJ Reiniger
ca36d1dce6 Adding callbacks for notifying when the distance per pulse changes (#861) 2018-01-02 16:53:39 -06:00
Sam Carlberg
ee33296e1f SmartDashboard override .name entry in putData(String, Sendable) (#866)
Fixes #865
2018-01-02 16:39:16 -06:00
Tyler Veness
0ef9803363 Update copyright year to 2018 (#864)
Also fix a few files with incorrect line endings.
2018-01-02 11:20:21 -06:00
Tyler Veness
eedb8910c3 Removed extra newlines from beginning of Java classes (#859)
The content of this PR was generated by styleguide#111.
2018-01-02 11:17:46 -06:00
Sam Carlberg
8346caed9c Move subsystem command metadata to metadata key format (#863) 2018-01-01 17:05:03 -05:00
PJ Reiniger
55b6764d50 Fix bugs in simulation libraries (#853)
Some thing got broken in the past couple of weeks with updates to the
HAL.
2017-12-31 14:37:14 -06:00
Thad House
2c4faee667 Fixes -Og compile and strip binaries (#838) 2017-12-29 22:18:35 -06:00
Jaci R
8d1dee16be Add DriverStation NetworkTables HAL Extension (#829) 2017-12-29 21:55:31 -06:00
Jaci R
76b182600a Add Low Fidelity NetworkTables simulation extension (#823) 2017-12-29 21:54:18 -06:00
sciencewhiz
c647a801ad Add Encoder Index as a child (#857) 2017-12-29 21:48:39 -06:00
sciencewhiz
02131639bc Add Digilent DMC 60 Speed Controller (#855) 2017-12-28 21:42:19 -06:00
Noah Gleason
566e283694 Make setDefaultCommand public (#854) 2017-12-28 12:48:15 -06:00
Peter Johnson
40eb6dfc9b Fix SmartDashboard PutData to hook setters. (#851)
* Fix SmartDashboard PutData to hook setters.

Also update all PutData values in main periodic loop (same as LiveWindow).

* Improve SmartDashboard.putData() repeat call handling.
2017-12-26 18:18:02 -05:00
Dustin Spicuzza
a3e5378d14 SPI: Check for null (#850) 2017-12-25 22:03:22 -06:00
Thad House
691741cfcb Fixes non public static methods in RobotController. (#852) 2017-12-25 20:26:05 -06:00
Thad House
166d9e01bf Add PWMVictorSPX (#842) 2017-12-17 19:59:30 -08:00
Thad House
7eab4371f4 Adds TriState DIO functionality to the HAL (#835)
Adds a function to raw set the DIO direction. Also adds a C++ unsafe
function to enable fast setting of DIO direction.
2017-12-14 00:17:29 -08:00
Peter Johnson
de134a5c60 Add deprecated shims for LiveWindowSendable and NamedSendable. (#834)
This will help prevent old code from breaking (not all cases, but should help).
2017-12-13 23:45:12 -08:00
Peter Johnson
7f074563d0 Add support for automatic SPI transfer engine. (#836)
The SPI Accumulator functions have been moved from HAL to wpilib and rewritten
to use the automatic transfer engine.
2017-12-13 23:41:37 -08:00
Thad House
d3dd586362 Revert "Fixes SPI bad chip select (#818)" (#822)
This is no longer required for image 2018v16.

This reverts commit b42285fddd.
2017-12-12 11:31:20 -08:00
Thad House
9c85105591 Update to image 2018v16 (#833) 2017-12-12 11:03:53 -08:00
Peter Johnson
86ac70a125 Fix wpilibcIntegrationTests RobotController warnings. (#832) 2017-12-11 22:15:29 -08:00
Austin Shalit
3c3a448d47 Deprecate SampleRobot (#472)
Suggest TimedRobot as an alternative.

Remove -Werror from examples to avoid breaking build.
2017-12-11 22:06:01 -08:00
Thad House
8744511f1d Fixes some methods in RobotController not being static. (#831) 2017-12-11 11:48:54 -08:00
Thad House
7729dd972f Fixes JNI symbol check (#830)
setErrorData symbol was missing. However, its been deprecated at the
netcomm level for years, and wasn't exposed in wpilibj. And it would
have been crashing since forever, so safe to remove.
2017-12-11 11:48:39 -08:00
Thad House
8b7aa61091 Adds RobotController class (#828)
Unifies random functionality from other classes
Deprecates all old functions.
2017-12-10 21:52:49 -08:00
Peter Johnson
88a6b4ac38 PIDController::InitSendable(): Use double, not bool for double values. (#827) 2017-12-10 20:58:29 -08:00
Peter Johnson
217b1a2259 VisionRunner: Add stop() function to stop a runForever() loop. (#826)
This was previously possible in Java with Thread.interrupt(), but provide
the same function in both C++ and Java.

Fixes #444.
2017-12-10 20:58:14 -08:00
Thad House
d2e7a90f41 Removes statics from hal sim (#825)
Based off of #824, the equivelent in sim.
2017-12-10 19:38:53 -08:00
Thad House
8bd48d6c34 Switches HAL to manual instead of static initialization (#824)
Only athena.

Will fix a whole lot of init issues.
2017-12-10 18:02:07 -08:00
Thad House
1fa0adb091 Removes MSVC and GCC old version workarounds (#821) 2017-12-08 23:40:35 -08:00
Thad House
f615e68a43 Require GCC 5 for wpilib build (#820)
Will help in season with teams not upgrading their GCC. Will have a
better error message.
2017-12-08 22:48:01 -08:00
Thad House
aa4f0ef4f8 Start using the new FRC compiler define (#797)
Remove all definitions from the MockData headers when in simulation mode.
Add a constexpr IsReal and IsSimulation in RobotBase.
2017-12-08 22:47:21 -08:00
Thad House
b42285fddd Fixes SPI bad chip select (#818)
Temporary workaround for 2018v13 image.
2017-12-08 21:42:30 -08:00
Thad House
8106fbdbea Removes custom CONFIG_ATHENA compiler directive (#796)
In roborio GCC 5.5, __FRC_ROBORIO__ has been added directly to the
compiler. So we can instead use that to detect if we are build for the
roborio, and in a much more reliable way.
2017-12-08 21:40:11 -08:00
Tyler Veness
942ba51765 Reclassified NetworkTables headers as "other library" (#775) 2017-12-07 23:34:29 -08:00
PJ Reiniger
33a08d5b34 Add halsim unit tests (#783)
Also adds function that can register all the callbacks at once.
Since all of the callbacks issue a string identifier, it makes it
possible and easy to have one function callback, and differentiate the
path to take based on the string.  Hooking up all the callbacks at once
makes it easier for the simulator developer to know when something was
added to wpilib rather than looking at the commits.
2017-12-07 22:42:20 -08:00
Thad House
4e3af0756d Removes workarounds for issues in image 10 (#816) 2017-12-06 21:20:03 -08:00
Thad House
5078f6c92a Update to image 2018v13 (#815) 2017-12-06 21:02:36 -08:00
Peter Johnson
899892c119 Change Utility to use Twine. 2017-12-05 00:17:56 -08:00
Peter Johnson
54326311ad Use Twine in error checks. 2017-12-05 00:17:56 -08:00
Peter Johnson
fe53dd2f28 Use Twine for error message inputs. 2017-12-05 00:17:56 -08:00
Peter Johnson
ab137abab5 Use llvm::Twine across C++ Command structure. 2017-12-05 00:17:56 -08:00
Peter Johnson
001dedf3b2 SmartDashboard: Use magic static for static initialization. (#812)
It's possible for SmartDashboard functions to be called from static
initializers in user code, so use a magic static to force initialization
order.
2017-12-04 23:50:27 -08:00
Peter Johnson
f9bece2ffb Update LiveWindow to provide continuous telemetry. (#771)
LiveWindow.updateValues() is now called from IterativeRobotBase on every
loop iteration.  Telemetry for all WPILib classes is enabled by default;
it can be disabled for specific classes using LiveWindow.disableTelemetry(),
or all telemetry can be disabled using LiveWindow.disableAllTelemetry().

This necessitated changing the hook methodology into other classes to
be more property-based rather than each class providing multiple functions.
This had the benefit of reducing boilerplate and increasing consistency.

- Remove NamedSendable, add name to Sendable.

- Provide SendableBase abstract class.

- Deprecate LiveWindow addSensor/addActuator interfaces.

- Add LiveWindow support to drive classes.

- Add addChild() helper functions to Subsystem.

- Fix inheritance hierarchy.  Now only sensors inherit from SensorBase.
  Other devices inherit from some combination of SendableBase, ErrorBase, or
  nothing.
2017-12-04 23:28:33 -08:00
Tyler Veness
3befc7015b Make MotorEncoderTest use LinearDigitalFilter's reference overload (#811) 2017-12-04 22:37:06 -08:00
Tyler Veness
de63e1c8a1 Fixed race condition between PIDController enable/disable and PIDWrite() call
To make this work in PIDController.java, the use of synchronized had to be
replaced with ReentrantLock and try-catch blocks. The locking in
PIDController.java was made equivalent to PIDController.cpp and some existing
race conditions in PIDController.java were fixed in the process.

Fixes #30.
2017-12-04 20:42:33 -08:00
Tyler Veness
a76b1aa800 Reduced scope of PIDController's critical sections
m_pidInput and m_pidOutput are considered constant after their construction.
Setting the input range, output range, tolerance, or continuous mode locks the
controller. m_error and m_result are held in temp variables and set at the end
of the calculation.

Getters of P, I, D, F, m_error, m_setpoint, m_result, and m_enabled lock the
critical section. P, I, D, F, and m_setpoint are retrieved at the beginning of
Calculate().

Fixes #40.
2017-12-04 20:42:33 -08:00
Tyler Veness
350b741adc Cleaned up SampleRobot template and added warning about disabling motor safety (#766) 2017-12-04 20:28:31 -08:00
Thad House
64bfdc1a69 Bail out of the integration tests if enable fails (#792)
A failure is much better then an infinite loop.
2017-12-04 20:24:26 -08:00
Tyler Veness
65cc85f68d Add reference constructors/factory methods to LinearDigitalFilter (#810)
Composition is less verbose with references than with smart pointers.
2017-12-04 20:12:06 -08:00
sciencewhiz
6a00dc7976 Re-Add PacGoat java example (#802) 2017-12-04 20:09:02 -08:00
Tyler Veness
e9e407a87d Replace C identifier lists with (void) (#809)
These changes were generated by wpilibsuite/styleguide#106.
2017-12-04 20:05:51 -08:00
Tyler Veness
59c4984ed6 Deprecated internal filter of PID controller (#746)
This was replaced with an external LinearDigitalFilter.
2017-12-04 20:05:02 -08:00
Peter Johnson
b428d1e4b3 Remove CANSpeedController interface. (#806)
CANJaguar is no longer supported, and CANTalon no longer uses this interface.
2017-12-04 20:03:07 -08:00
Thad House
0994364591 Fixes cross module base class statics (#779) 2017-12-03 00:05:05 -08:00
sciencewhiz
0b8d3f0260 Update SampleRobot template to match comments (#768) 2017-12-02 23:28:52 -08:00
sciencewhiz
52eba45c51 Add missing documentation for squaredInputs for RobotDrive (#805) 2017-12-02 22:31:51 -08:00
Thad House
9090a82ef5 Fixes halsim sources and headers zips (#804) 2017-12-02 22:30:54 -08:00
Peter Johnson
2a69a4c7dc Revert #780 (don't kill FRC_NetCommDaemon). (#795)
This commit reverts commit 0f3f5218ad.
2017-12-01 23:47:01 -08:00
Thad House
9d2393f97e Waits 10 seconds between running the C++ and Java test (#798)
Potentially will fix java tests not enabling.
2017-12-01 23:45:49 -08:00
Peter Johnson
dae619b006 Add error reporting to AbstractComsSetup test initialization. (#800) 2017-12-01 23:44:11 -08:00
Thad House
9c06d2878b Update to latest native plugin (#799)
This is what prints warnings to console.
2017-12-01 16:23:30 -08:00
Peter Johnson
e3a2abdf97 HAL_SetDigitalPWMRate(): Use same logic as LabView. (#794) 2017-12-01 10:26:40 -08:00
Peter Johnson
7867e906e9 NidecBrushless: Have disable() call PWM.setDisabled(). (#763)
This provides a way to stop motor operation even if the DIO is disconnected.

Also change Set() to enable the PWM instead of having the constructor do it.

Provide an explicit Enable() call to re-enable after Disable() is called.
This is different from the other motor controllers (which automatically
re-enable when Set() is called) due to the dual-wiring of this motor
controller.

Motor safety results in disabling the motor only until the next Set() call.
2017-12-01 00:43:11 -08:00
Peter Johnson
65a044f633 Fix HAL_CleanNotifier race. (#793)
This race was caused by holding a lock while calling into FRC_ChipObject,
which was waiting for the callback to exit before returning, and our
callback wanted to grab the same lock.
2017-11-30 20:45:40 -08:00
sciencewhiz
cbd08a1e11 Add tests for equivilance of RobotDrive and DifferentialDrive/MecanumDrive (#732)
Add documentation for how to get same results as RobotDrive and improve
RobotDrive documentation
2017-11-29 21:41:00 -08:00
sciencewhiz
e308dd28f3 Fix javadoc link in Solenoid.java (#789) 2017-11-29 21:33:29 -08:00
Thad House
fa0b4428e9 Runs DS enabled loop in process (#785)
Solves mutex issues, and other issues with the existing teststand
software. And simplifies the unit test structure.
2017-11-28 19:12:05 -08:00
Tyler Veness
26a36779a6 Performed cleanup of Timer's free functions (#776)
* GetClock() is now officially deprecated since its comment already informally
  did so and the function just forwards to Timer::GetFPGATimestamp().
* The declaration of GetPPCTimestamp() is missing a definition and has been
  removed.
* std::this_thread::sleep_for() returns immediately when given a negative
  duration, so the check for that was removed from Wait().
2017-11-27 21:59:00 -08:00
Tyler Veness
dfc0656e5c Fix wpilibj FilterOutputTest null pointer exception (#778) 2017-11-27 12:28:25 -08:00
Peter Johnson
0f3f5218ad Kill FRC_NetCommDaemon as well as robot programs. (#780)
Also use flock on Jenkins side to prevent multiple simultaneous runs, instead of using teststand mutex.
2017-11-27 12:24:46 -08:00
Tyler Veness
34c44b7ae9 Improved Drive docs and fix implementation bugs (#774)
I also found some inconsistencies in MecanumDrive and KilloughDrive and fixed
them.

Drive now uses the NED axes convention. Therefore, the positive X axis points
ahead, the positive Y axis points to the right, and the positive Z axis points
down.

Translation in X assumes forward is positive. Translation in Y assumes right is
positive. Rotation rate assumes clockwise is positive. Angles are measured
clockwise from the positive X axis.

Based on the angle origin convention, DrivePolar() for both Mecanum and Killough
needed the normalization removed, sine used to compute the Y component, and
cosine used to compute the X component.

The vector rotation done in DriveCartesian() needs to rotate by a negative angle
instead of positive to undo the robot's rotation. RobotDrive assumed a clockwise
angle and sensors returned counter-clockwise angles, which is why it used a
positive angle for rotation.
2017-11-26 18:36:51 -08:00
sciencewhiz
7a250a1b93 Implement PCM One Shot feature. Fixes artf4731 (#539) 2017-11-26 12:55:21 -08:00
Caleb Smith
a338ee8be0 Add PIDController Wrapping (#601) 2017-11-25 21:15:33 -08:00
sciencewhiz
c9d440f338 Fix Java Compressor test. Make limits same as C++. (#772) 2017-11-24 20:14:36 -08:00
Tyler Veness
a00b2449db Removed unused includes and replaced Ultrasonic's std::set with std::vector (#767) 2017-11-23 20:46:24 -08:00
Tyler Veness
5c659fdcdf Deprecated PIDController::SetTolerance() (#764)
PIDController::SetPercentTolerance() behaves identically to it, so removing
SetTolerance() leaves one obvious way to do absolute or percent tolerance.
2017-11-23 01:21:36 -08:00
Thad House
d36d72bd4f Fixes MotorSafetyHelper locking and race conditions (#762)
Closes #760
2017-11-23 00:36:57 -08:00
sciencewhiz
614093c0c4 Fix documentation for getMatchTime in Timer class to match DriverStation (#761) 2017-11-23 00:19:05 -08:00
PJ Reiniger
12c4418bda Added callbacks for CAN (#757)
Added callback scheme for a pass through to something higher
level.  Since the ID is embedded into the arbitration ID, and some
devices can use different schemes whether it is plugged in through a
device or put into the daisy chain (pigeonImu), I made one "internal
data object" for max reusability.
2017-11-22 19:48:32 -08:00
Caleb Smith
0431cf97ff Cleanup PIDController (#597) 2017-11-22 18:56:35 -08:00
Tyler Veness
ba879f4663 Cleaned up variable names for std::lock_guard and their associated mutexes (#759) 2017-11-22 17:10:21 -08:00
Tyler Veness
96de0b5b11 Variable name fixes (#758) 2017-11-22 17:06:57 -08:00
Tyler Veness
85157a56c3 CircularBuffer now uses an idiomatic interface in C++ and Java (#421) 2017-11-22 17:04:57 -08:00
Tyler Veness
029246ed28 Replaced extra constructors in LinearDigitalFilter with llvm::ArrayRef<> (#755)
llvm::ArrayRef<> replaces both the std::initializer_list<> and std::vector<>
constructor overloads.
2017-11-20 21:23:00 -08:00
sciencewhiz
6377ab774d Allow deprecated warnings for tests (#756) 2017-11-20 21:21:50 -08:00
Tyler Veness
05e581f409 Fixed crash in wpilibj SampleRobot (#753)
robotInit() and HAL.observeUserProgramStarting() should be called in
startCompetition() rather than the constructor.

Fixes #752.
2017-11-19 22:47:39 -08:00
Peter Johnson
c73dd807e1 ErrorBase: Remove last use of sstream and iostream. (#750) 2017-11-19 20:16:42 -08:00
Tyler Veness
7a0dd9baa9 Add return-to-zero test for LinearDigitalFilter moving average (#751)
Ensures LinearDigitalFilter moving average returns to zero after non-zero
values are inserted.

Tests for issue #642
2017-11-19 20:16:09 -08:00
Tyler Veness
11f37683c3 Added constructor to PIDController that takes references instead of pointers (#745) 2017-11-19 19:06:00 -08:00
Tyler Veness
5af0c9c101 Replaced const variables with constexpr (#731) 2017-11-19 19:04:28 -08:00
Tyler Veness
259461aee9 Added PIDController::GetAvgError() back in (#749)
It got removed during the LinearDigitalFilter change (#38) instead of deprecated
by mistake.
2017-11-19 18:23:48 -08:00
Peter Johnson
d214b36786 Change HAL notifier to polling. (#627)
This moves the thread code to the WPILib layer, fixing various potential
races and significantly simplifying the HAL implementation.
2017-11-19 17:58:40 -08:00
Tyler Veness
4a07f0380f PIDController class now uses LinearDigitalFilter for filtering velocity instead of internal queue (#38) 2017-11-19 15:58:30 -08:00
Peter Johnson
7f46b50b21 Unify WPI_Now and HAL_GetFPGATime. (#743)
Depends on wpilibsuite/wpiutil#56.
2017-11-19 12:33:36 -08:00
PJ Reiniger
303c259b89 Simulate ADX* family of accelerometers and gyros (#688) 2017-11-18 12:31:51 -08:00
Thad House
cd1dbb1e3a Adds a const buffer listener (#742)
Replaces need for const_cast in SPI and I2C functions
2017-11-17 10:01:49 -08:00
Peter Johnson
a20474bfc7 Update sensors to not use direct byte buffers. 2017-11-17 09:36:57 -08:00
Peter Johnson
479d0beb5a SerialPort: Use byte[] instead of ByteBuffer in JNI. 2017-11-17 09:36:57 -08:00
Peter Johnson
b93aa176d6 AnalogInput: Remove byte buffer usage. 2017-11-17 09:36:57 -08:00
Peter Johnson
9021b37fd2 I2C: Provide byte[] JNI interfaces.
This avoids a direct byte buffer allocation on every read/write/transaction
on the byte[] variants.

Changes HAL I2C interfaces to use const for dataToSend.
2017-11-17 09:36:57 -08:00
Peter Johnson
6307d41002 SPI: Provide byte[] JNI interfaces.
This avoids a direct byte buffer allocation on every read/write/transaction
for the byte[] variants.

Also change spiGetAccumulatorOutput() to directly set the AccumulatorResult
object, avoiding a ByteBuffer allocation.

Changes HAL SPI interfaces to use const for dataToSend.

Fixes #733.
2017-11-17 09:36:57 -08:00
Peter Johnson
df7c1389de Remove ni-libraries libi2c and libspi. 2017-11-16 23:01:28 -08:00
Peter Johnson
6accc31ee7 HAL: implement I2C and SPI directly instead of using i2clib and spilib.
This reduces library dependencies, improves error handling, and makes
future enhancements easier.
2017-11-16 23:01:28 -08:00
Thad House
f56ec10bcf Only return lower 32 bits of FPGA time (#741)
Works around an NI bug in image 10.
2017-11-16 20:52:50 -08:00
Tyler Veness
e5e6d6a193 Ran formatter based on styleguide#95 (#737) 2017-11-16 01:05:20 -08:00
Tyler Veness
c663d7cd16 Reflowed comments and removed commented out code (#735) 2017-11-16 00:33:51 -08:00
Tyler Veness
1e8d18b328 Upgrade Travis CI Python version to 3.5 (#740) 2017-11-16 00:19:16 -08:00
Peter Johnson
c2d95db3ab Fix PreferencesTest. (#739) 2017-11-15 23:56:17 -08:00
Thad House
dd7563376b Force load OpenCV and cscore libraries on program initialization (#716)
Fixes bugs where Mat's are initialized before anything cscore was
called.
2017-11-14 22:04:53 -08:00
Tyler Veness
14fcf3f2f0 Simplified PIDController integration logic (#645)
A clamp() helper function was written based on C++17's std::clamp().
2017-11-13 22:28:55 -08:00
Peter Johnson
020ee227d2 Move ctre headers to hal/src so they aren't user-visible. (#728)
Also removes ctre_frames.h entirely since it's not used.

Fixes #683.
2017-11-13 22:23:18 -08:00
Peter Johnson
4d559f3856 Use wpi::mutex instead of std::mutex. (#730)
This uses a priority-aware mutex on Linux platforms.

Fixes #729.
2017-11-13 09:51:48 -08:00
Thad House
35d68d2a34 Adds ability to simulate joysticks and event info (#727)
Thanks @pjreiniger for the initiali implementation and work on this.
2017-11-12 19:33:43 -08:00
Peter Johnson
7007725d9f SerialHelper: Check error_code to prevent infinite loop. (#725) 2017-11-11 22:13:59 -08:00
Tyler Veness
0c83cad70c Upgraded clang-format to 5.0 (#431) 2017-11-11 22:09:51 -08:00
sciencewhiz
0001047b8b Add NidecBrushless to WPILib.h (#724) 2017-11-11 16:35:43 -08:00
Thad House
c885251367 Fixes HALSim_Print build to be the standardized pattern (#721)
Now publishes in zips, and with proper artifacts.

The code files just moved, and no changes.
2017-11-10 19:26:33 -08:00
Tyler Veness
42096fac3f Ran formatter (#722) 2017-11-10 18:29:27 -08:00
sciencewhiz
6be9e69d13 Switch Command Templates to TimedRobot (#719) 2017-11-09 20:08:41 -08:00
Thad House
7bbd13d914 Adds match specific calls to Java and C++ (#720)
Uses caching, matching the joystick calls.
2017-11-09 19:59:29 -08:00
Thad House
2225c4fee2 Fixes warnings for casts in sim interrupt functions (#718) 2017-11-09 14:01:24 -08:00
Tyler Veness
7efab4c43a Replaced ternary operators with if statements (#346)
Instances of the ternary operator were replaced with if statements to make the code base more consistent.
2017-11-08 23:44:03 -08:00
Thad House
c8e44256ef Uses NI provided function for SetOccurDataRef rather then importing the symbol ourselves. (#714) 2017-11-08 23:41:16 -08:00
Peter Johnson
f3cd883c5c Add Nidec Brushless motor. (#705) 2017-11-08 23:40:01 -08:00
Thad House
f34c736fb2 Adds warning prints to native library builds (#710)
Can be disabled with -PskipWarningPrints
2017-11-08 23:14:21 -08:00
Tyler Veness
1276489961 Removed uses of deprecated functions (#709) 2017-11-08 21:29:29 -08:00
Tyler Veness
8b2e656bde Fixed Java velocity PID not calculating result when P = 0 (#717) 2017-11-08 21:28:09 -08:00
Thad House
6e9d1f55c6 Updates image to 2018 v10 image (#713) 2017-11-08 11:26:11 -08:00
Thad House
f4dce9e608 Fixes receive size in Java I2C (#715)
Allows underrun, which matches c++ behavior.

Fixes #711
2017-11-07 18:43:23 -08:00
Thad House
b9aabc71b0 Fixes publishing basenames for examples to make combiner script work. (#712) 2017-11-07 14:54:17 -08:00
Jaci R
0d54772362 Add IDEA plugin to root project (#707) 2017-11-05 19:57:53 -08:00
Tyler Veness
faf134a674 C++ examples no longer use deprecated APIs (#703) 2017-11-05 19:39:47 -08:00
Thad House
c24e755409 Fixes java example publishing and xml file (#706) 2017-11-04 10:09:41 -07:00
Thad House
bee9f1cb17 Adds header task to print out all headers (#704)
Will be used to create a generator for IDE's to get include paths.
2017-11-03 22:50:06 -07:00
Tyler Veness
45d48d6b5a Cleaned up C++ examples (#672) 2017-11-03 13:22:56 -07:00
Peter Johnson
6401aa1fde SerialHelper: Use llvm path functions instead of popen. (#702)
This avoids a fork that causes an out-of-memory error in Java.

Depends on wpilibsuite/wpiutil#43
2017-11-03 12:30:56 -07:00
Thad House
6af4940c22 Adds HAL calls for match data from DS (#691) 2017-11-01 21:58:44 -07:00
Sam Carlberg
237b2df82f Add .type metadata to preferences table (#701)
Allows shuffleboard to automatically discover the type, instead of inflexibly hardcoding it
2017-10-30 21:50:49 -07:00
Peter Johnson
a70687aaec Improve error reporting for the new TCP netconsole. (#700)
Fixes #695.
2017-10-30 21:50:14 -07:00
sciencewhiz
fbfe85568b Fix preferences test (#699) 2017-10-29 21:30:50 -07:00
Tyler Veness
595b1df380 Fixed minimum number of joystick axes (#696) 2017-10-29 17:21:50 -07:00
Thad House
efc7770e9b Fixes NPE in DriverStation initialization (#694)
Introduced by #626.
2017-10-27 23:16:42 -07:00
Tyler Veness
21585f70a8 Added functions for detecting button press and release events (#626)
I also shuffled around the HID interfaces to be more intuitive, deprecated some
Joystick and XboxController member functions, and deprecated the JoystickBase
and GamepadBase classes.

Supersedes #89.
2017-10-27 21:45:56 -07:00
Tyler Veness
c33fca34e9 Added TimedRobot template (#673) 2017-10-27 21:33:04 -07:00
PJ Reiniger
de95f08a10 Adding call to notify program started (#692)
Causes the HALSIM_WaitForProgramStart loop to break, essentially
notifying simulators the robot is good to go.
2017-10-27 21:00:52 -07:00
Thad House
90f99dc571 Adds PWM to LoopTiming and CycleStart HAL calls (#693) 2017-10-27 19:44:40 -07:00
Thad House
f34332643a Uses new FPGA calls to get 64 bit FPGA time and 64 bit PWM cycle start time. (#687) 2017-10-27 18:03:10 -07:00
Tyler Veness
4ab095e9c9 Fix formatting in CameraServer.cpp (#689)
A PR didn't rerun the formatter before merging.
2017-10-27 11:35:57 -07:00
Thad House
541753c814 Updates to 2018 v9 image (#686) 2017-10-27 00:47:56 -07:00
Jeremy White
f02bb058bd Set the llvm standard output stream to be unbuffered. (#678)
This is particularly useful for the simulation when invokved
inside Eclipse.  Otherwise, you won't see the robot starting
message.
2017-10-27 00:46:56 -07:00
sciencewhiz
12e96c6f13 Add usage reporting to CameraServer (#682) 2017-10-27 00:45:54 -07:00
Austin Shalit
b65447b6f5 Fix spelling typos (#595) 2017-10-27 00:44:51 -07:00
Tyler Veness
9945a5b3c6 Ran formatter (#681) 2017-10-26 19:28:59 -07:00
Thad House
ce4c9edd1f Fixes halsim_print to not try and build when the 'onlyAthena' flag has been set (#685)
Building a non-athena library in athena only is not possible.
2017-10-25 10:52:35 -07:00
PJ Reiniger
a6e6ae41b9 Add function that can register all the HAL callbacks at once (#646)
Since all of the callbacks issue a string identifier, it makes it
possible and easy to have one function callback, and differentiate the
path to take based on the string.  Hooking up all the callbacks at once
makes it easier for the simulator developer to know when something was
added to wpilib rather than looking at the commits.
2017-10-21 22:45:41 -07:00
Austin Shalit
f4e2e41aaf Remove leading '*' from license and rename to LICENSE.txt (#596) 2017-10-21 16:04:57 -07:00
Thad House
1e528669ff Adds publishing for examples and templates so they can be grabbed from eclipse (#674) 2017-10-21 15:33:42 -07:00
Thad House
a1ea448406 Adds JNI call to get CANStatus (#677)
Call already existed in the HAL.
2017-10-21 15:32:05 -07:00
Tyler Veness
9dc1de1d09 Specified angle units for Vector2d rotate() function. (#679)
Fixes #676.
2017-10-21 15:29:39 -07:00
Tyler Veness
0521d85048 Moved comment after include line so include order is determined properly (#680) 2017-10-21 15:28:46 -07:00
PJ Reiniger
3c842d8234 SPI and I2C simulator (#662)
* Creating SPI and I2C simulation abilities

* Update the callback helpers to support different function callback
types
* Create callback type that uses a buffer
* Created I2C/SPI data classes that manage the callbacks and don't do
much of anything else

* Ran format, cleaned up some issues
2017-10-18 23:01:58 -07:00
Jeremy White
be77f9cb26 Pull request for the Extensions interface only (#655)
* Modify halsim to be able to load extension libraries if they are available.

It will read the list of libraries to try from the HALSIM_EXTENSIONS
environment variable.  Multiple libraries can be given if separated
by ';' (Windows) or ':' (Unix).

The library must have an 'HALSIM_InitExtension' method that returns >= 0 on success.

The library is expected to use the interface expressed by
  hal/src/src/main/native/include/MockData

* Add a simple halsim library that just prints robot values.

This makes a good test bed for cross platform purposes,
and provides the ultimate in light weight simulators.

This initial version only prints PWM values.
2017-10-18 00:27:55 -07:00
Austin Shalit
2fc60680f4 Remove RedundantModifiers (#578) 2017-10-17 21:47:55 -07:00
Tyler Veness
0291a95f68 Add cpp examples (#659)
* Added C++ robot project examples and set up sub .clang-format for them

* Ran formatter
2017-10-17 21:37:58 -07:00
Austin Shalit
66002d6cac [WIP] Move examples to allwpilib (Java) (#569)
* Move examples to allwpilib

* Add checkstyle config to examples project

* Ran wpiformat

* Run checkstyle on examples

* Change maximum line length for examples to 80 chars

This number was chosen based on testing of the number of characters shown by default in Eclipse done by @Kevin-OConnor: 51 chars by default on an E09 @ 1024x600 (which has the welcome window open on the right), 71 with welcome closed, 95 with the right-hand outline pane closed

* Add mavenCentral repository

* Rename subproject & error on deprecated API use

* Remove deprecated API usage
2017-10-16 22:30:21 -07:00
Tyler Veness
a7e9ac1062 Fix capitalization of class names in PIDToleranceTest.cpp (#588) 2017-10-16 21:16:33 -07:00
Thad House
434d60592c Adds HAL_Initialize to ErrorBase constructor, and makes HAL_Initialize properly reentrant (#668)
Partial fix to #663, and most likely the best we are going to be able to
get.
2017-10-16 20:00:32 -07:00
Thad House
ee20747255 Adds WPILib JNI shared debug file publish. (#671) 2017-10-16 19:59:05 -07:00
Tyler Veness
f4779379c3 Added brace comments (#670)
Enforced by wpilibsuite/styleguide#80.
2017-10-16 19:56:08 -07:00
Austin Shalit
877a9eae1f Add SpeedControllerGroup (#362) 2017-10-16 19:54:36 -07:00
Thad House
24752a9751 Removes OpenCV dependency from wpilibJNI (#667)
Not exactly sure why it was there in the first place. Closes #664
2017-10-12 18:25:17 -07:00
Thad House
e1dc099517 Updates to the 2018v5 image (#665) 2017-10-12 18:24:39 -07:00
Sam Carlberg
f0cc623241 Change metadata format to dotfile, make certain entries metadata (#666)
Sendable's "Name" is now ".name"
Sendable's "Subsystem" is now ".subsystem"
Command's "name" is now ".name"
Command's "isParented" is now ".isParented"
2017-10-11 20:27:49 -07:00
Jacob Caporuscio
ba3a85d0cc Changes TalonSRX to PWMTalonSRX in wpilibj and wpilibc. (#656)
Also brings the java kResourceType list up-to-date with the cpp list.
2017-10-11 12:01:50 -07:00
Thad House
79919a5f1c Moves wpilibc link script into shared folder (#660) 2017-10-08 10:42:09 -07:00
Thad House
94ea5bfb06 Move published wpilibj JNI shared artifact into shared/ subfolder (#658)
Makes eclipse easier.
2017-10-07 15:31:36 -07:00
Thad House
24680bbd53 Change link script artifact id (#657) 2017-10-07 12:08:53 -07:00
Peter Johnson
7fab0e0ef2 Depend on wpiutil 3.+, ntcore 4.+, cscore 1.+ rather than just +. (#651)
Also update to wpilib-version-plugin 2.0.
2017-10-01 10:57:03 -07:00
Tyler Veness
dd66b23845 Remove priority mutex (#644)
* Removed hal::priority_condition_variable

* Replaced uses of priority mutexes with std::mutex and std::recursive_mutex

This allowed replacing a use of std::condition_variable_any with
std::condition_variable.

* Replaced all uses of std::recursive_mutex with std::mutex equivalents
2017-09-28 23:32:35 -07:00
Tyler Veness
19addb04cf Split RobotDrive class into a class for each drive type (#552)
DiffDrive.CurvatureDrive (aka CheesyDrive) and KilloughDrive were also added.
This reorganization paves the way for SwerveDrive.
2017-09-28 23:30:00 -07:00
pjreiniger
abb66d3e4b Replace FRC_NetworkCommunication CAN in wpilibj with HAL CAN (#650) 2017-09-28 22:40:04 -07:00
pjreiniger
db4981f166 Java now asks the HAL if it is a simulation or not (#647) 2017-09-23 07:56:53 -07:00
Tyler Veness
6e1be897de Ran formatter (#643) 2017-09-19 21:55:36 -07:00
sciencewhiz
423d8f6860 Add missing usage reporting. (#639)
Compressor C++/Java
Servo C++
2017-09-19 21:17:27 -07:00
Jeremy White
eb38204d1a Update the README to note the need for gcc 5+ and Visual Studio (#640)
Update the build requirements in the README.  Add a note about
Visual Studio, the need for gcc 5, and remove the style guide;
it is mentioned further down, and it is not a requirement for building.
2017-09-19 21:14:53 -07:00
Tyler Veness
1711291cd8 Fix Travis build (#641)
Travis now installs pip3 explicitly.
2017-09-19 21:13:03 -07:00
Peter Johnson
57ba58917d PreferencesTest: Use new NetworkTables API. (#636)
This avoids deprecated warnings from the old API.
2017-09-07 22:40:18 -07:00
Thad House
2249a8bac0 Adds a HAL wrapper around the CAN API's (#623)
Can someday be added to the simulator. Removes the last use case for the
ni headers directly.
2017-09-07 21:40:30 -07:00
Thad House
c572e6a307 Adds the rest of the data needed for a publish on jenkins (#628) 2017-09-07 21:07:01 -07:00
Tyler Veness
e444b6015c Updated remaining .styleguide files to new config file format (#635) 2017-09-07 21:02:52 -07:00
Tyler Veness
38dbed8e09 .styleguide now uses generalized config file format (#621)
Requires styleguide#66.
2017-09-06 23:00:10 -07:00
Peter Johnson
34c18ef000 Remove getTable from wpilibj Sendable interface.
This allows nearly all m_table member variables to be removed.
2017-09-06 22:29:04 -07:00
Peter Johnson
0d4fde17e0 Remove GetTable from wpilibc Sendable interface.
This allows nearly all m_table member variables to be removed.
2017-09-06 22:29:04 -07:00
Peter Johnson
040a8c6bcc Update wpilibc to use new NetworkTables package and interfaces. 2017-09-06 22:29:04 -07:00
Peter Johnson
4e80570c4c Update wpilibj to use new NetworkTables package and interfaces.
This may be breaking to CANSpeedController implementations.
2017-09-06 22:29:04 -07:00
Peter Johnson
91529cc435 Update NetworkTables for new API.
This fixes breakages due to the JNI move.

Depends on: https://github.com/wpilibsuite/ntcore/pull/204
2017-09-06 22:29:04 -07:00
Peter Johnson
ef3267833f Fix IterativeRobot/TimedRobot RobotInit(). (#633)
In C++, it's not legal to call a virtual function from within a constructor,
so the user override was never called (the base function is always called).

See https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctors

While this is technically allowed in Java, also change Java for consistency.
2017-09-05 23:57:26 -07:00
sciencewhiz
a5ef50c9e7 Add documentation for PeriodMultiplier (#632) 2017-09-04 22:03:02 -07:00
sciencewhiz
6eee457898 Renable javadoc fail on error (#631)
Remove reference check and fix HTML error
2017-09-03 14:10:40 -07:00
Thad House
fb6d7b3470 Fixes javadocs (#630) 2017-09-02 21:29:30 -07:00
sciencewhiz
2d78fdabb8 Fix recieve typo in JNI names. (#629)
Fixes #594
2017-09-01 22:48:33 -07:00
Thad House
94c31ceeb1 Gets wpilib compiling with skipAthena and onlyAthena flags (#625) 2017-08-31 21:29:35 -07:00
Peter Johnson
67d4da51ee Restore travis support. (#608)
Travis no longer builds athena, as we no longer support 14.04 as a build
platform.  It also does not build the dev or test executables due to
system library symbol differences on 14.04.
2017-08-27 02:14:33 -07:00
Tyler Veness
6e4f66cc8b Classify other libraries' headers properly and fix committed formatting issues (#620) 2017-08-27 00:11:52 -07:00
Tyler Veness
a4e781a231 Fixed spacing and comment annotations around namespace and extern declarations (#587) 2017-08-24 00:07:46 -05:00
Tyler Veness
f151892db5 Contents of copyright line now has more standard ordering (#585) 2017-08-24 00:06:13 -05:00
Austin Shalit
c45fb73f36 Convert for loops to foreach loops (#592) 2017-08-24 00:00:55 -05:00
sciencewhiz
848280d1f1 Improve C++ Compressor documentation based on Java's docs. (#607) 2017-08-23 23:58:21 -05:00
Peter Johnson
f7016b359f HALUtil: Update to new GetJavaStackTrace function. 2017-08-22 23:09:28 -05:00
Peter Johnson
be58a279a5 Cross-platform JNI sometimes has jlong != int64. 2017-08-22 23:09:28 -05:00
Peter Johnson
909e6c4857 Error.cpp: Use llvm path function instead of OS basename.
This fixes an issue with the mac build.
2017-08-21 17:20:43 -05:00
Peter Johnson
5c0b08f4f5 Turn off -Wunused-const-variable on Mac. 2017-08-21 17:20:43 -05:00
Peter Johnson
05d1cfa276 Add "override" qualifier to several headers.
clang on Mac generates warnings for these.
2017-08-21 17:20:43 -05:00
Peter Johnson
ae675ae4e1 DriverStation: Work around missing pthread_local on Mac. 2017-08-21 17:20:43 -05:00
Peter Johnson
d3b636d073 fpga_clock: Don't use constexpr for time_points.
These are not constexpr on some compilers.
2017-08-21 17:20:43 -05:00
Peter Johnson
8b460f5944 sim DriverStation: Fix missing includes. 2017-08-21 17:20:43 -05:00
Tyler Veness
bdfa32876b Fixed Gradle test task name (#617) 2017-08-21 17:15:38 -05:00
Tyler Veness
4a3472ebb2 Removed unused include in PIDCommand.cpp (#616) 2017-08-20 17:09:13 -07:00
Thad House
9c804c1351 Fixes builds with skipAthena and onlyAthena, and mac builds (#613)
Did these in cscore and the other repos, but forgot about some of the
oddities jenkins has.
2017-08-19 22:15:52 -07:00
Tyler Veness
2a9c454baa Cleaned up and updated .styleguide for new build system file locations and ran wpiformat (#612) 2017-08-19 22:14:34 -07:00
Thad House
1a9a6c3678 Fixes HalSimStaticDeps config and publishing (#610) 2017-08-19 11:32:49 -07:00
Thad House
e1195e8b9d Update to 2018_v4 image and new build system. (#598)
* Revert "Force OpenCV to 3.1.0 (#602)"

This reverts commit 50ed55e8e2.

* Removes Simulation

* Removes old build system

* Removes old gtest

* Adds new gmock and gtest

* Updates to new ni-libraries

* removes MyRobot (to be replaced)

* moves files to new location

* Adds new sim backend and new test executables

* updates .styleguide and .gitignore

* Changes cpp WPILibVersion to a function

MSVC throws an AV with the old version.

* Disables USBCamera on all systems except for linux

* 2018 NI Libraries

* New build system
2017-08-18 21:35:53 -07:00
Thad House
50ed55e8e2 Force OpenCV to 3.1.0 (#602)
Will break otherwise when I push a new version
2017-08-13 21:41:45 -07:00
Tyler Veness
d682295ccd Miscellaneous cleanups for HAL, wpilibc, and wpilibj JNI (#589)
* Static functions in the HAL implementation were placed in the hal namespace
* "using namespace" declarations in HAL/cpp/Log.h and Timer.cpp were replaced
  with "using" declarations for std::chrono
* An extra include was removed from AnalogGyro.cpp
* InterruptableSensorBase's constructor was defaulted
* Newlines were added to some wpilibc integration tests for grouping
* A variable in HALUtil.h was renamed to follow the style guide

Supersedes #586
2017-08-07 17:36:34 -07:00
Austin Shalit
5e19c1881f Use diamond operator 2017-08-07 17:31:16 -07:00
Austin Shalit
617ff52f18 Use generics 2017-08-07 17:31:16 -07:00
Peter Johnson
5d3af62c0e Remove use of std::chrono_literals (C++14 feature). (#574) 2017-08-04 20:44:33 -05:00
Austin Shalit
ddd5aeba19 Checkstyle 8.1 (#584)
Added a few checks too:
- SimplifyBooleanExpression
- SimplifyBooleanReturn
- StringLiteralEquality
- UnnecessaryParentheses
2017-07-28 22:24:05 -07:00
Peter Johnson
3cfcbe9a95 Remove Scheduler.java from the sim path. (#564)
This is an old version and is duplicative of the shared Scheduler.java.
2017-07-27 00:41:56 -07:00
Tyler Veness
6bc793505d Suppress MultipleTopLevelClasses warning (#581) 2017-07-26 23:15:00 -07:00
Austin Shalit
3b44160cff Rearrange some method calls so methods fail faster (#583) 2017-07-26 23:14:35 -07:00
Thad House
d9586c8d38 Fixes JNI aliasing issues involving ControlWord and AllianceStation (#575) 2017-07-26 20:59:40 -07:00
Austin Shalit
74df3fac4e Require non null (#580)
* Replace null checks with Objects.requireNonNull()

* Use PMD rule instead of checkstyle rule
2017-07-18 20:32:08 -07:00
Austin Shalit
06321b8e87 Fix encoder sourceA null check (#579) 2017-07-18 19:34:45 -07:00
Thad House
f3efb948fe Switches CANJNI to use byte[] rather then ByteBuffer, and throws exceptions for invalid platforms (#571)
Fixes #567
2017-07-10 20:33:34 -07:00
Tyler Veness
432c03bf63 Updated Gradle to 4.0.1 (#573)
New PMD checks required modifying PIDController
2017-07-10 20:31:20 -07:00
Austin Shalit
bfd224278b Fix Java MyRobot linting (#572) 2017-07-10 20:29:52 -07:00
Tyler Veness
822ea6abc8 Made SpeedController class organization consistent between languages (#568) 2017-07-09 19:43:56 -07:00
Tyler Veness
97437ee58b Miscellaneous formatting and style fixes for integration tests (#570)
Added newline before comment block and replaced angle brackets around includes
with quotation marks. All other integration tests use quotation marks for WPILib
includes.
2017-07-09 19:27:43 -07:00
Thad House
aa7fe0db29 Fixes unused buffer warning on platforms other then athena (#566) 2017-07-09 08:59:26 -07:00
Thad House
237685d4a5 Fixes static initialization of HAL handles (#565) 2017-07-08 22:04:01 -07:00
Thad House
abbe630274 Gets WPILib building on windows and C++11 vs C++1y (#561) 2017-07-08 14:17:21 -07:00
Tyler Veness
89d3b08e77 Added TimedRobot (#520) 2017-07-08 07:50:56 -07:00
Thad House
f826216a28 Gets JNI compiling on all platforms (#563) 2017-07-08 07:48:27 -07:00
Austin Shalit
aa0a874ad0 Add periodic method to subsystems (#528)
Fixes #526.
2017-07-02 23:02:41 -07:00
Thad House
2da26c0579 Make HAL_Initialize timeout configurable, makes result a bool, and makes Java an exception rather than assert. (#557) 2017-07-01 00:43:06 -07:00
Tyler Veness
d34c844900 Fixed function ordering in robot base classes (#553) 2017-06-30 22:12:28 -07:00
Tyler Veness
68b63632c4 Removed functions that have been deprecated for at least one year (#551) 2017-06-30 22:05:33 -07:00
Chris Gregory
d2de94778e Remove memory leak in ConditionalCommand (#537)
This also properly handles nullptrs passed into ConditionalCommand
instead of having Undefined Behavior or NullPointerExceptions.
2017-06-30 22:01:21 -07:00
Austin Shalit
4fd4a50d41 Update Preferences to not use deprecated APIs (#555) 2017-06-30 19:38:32 -07:00
Tyler Veness
9d93820717 Replaced STL streams with LLVM's raw_ostream (#344)
std::cout and std::printf were replaced with llvm::outs() and std::cerr was replaced with llvm::errs().
2017-06-30 19:33:43 -07:00
Thad House
c57a7f0a41 Switches all notifiers created with the external API to be threaded (#546)
Testing showed this wasn't an issue with timing, and allows for more
safety in user code making mistakes. Places where the extra thread
wouldn't help have been kept non threaded, using a new internal API.
2017-06-30 18:58:58 -07:00
Thad House
1d15fcd072 Prints error when HAL_GetFPGATime call fails in fpga_clock. (#558) 2017-06-30 18:46:50 -07:00
Thad House
e824b1129e Adds way to reset and version all HAL handles (#545)
Useful in the sim to force a full reset. On roboRIO, the information is
still created and added, but is not checked because of speed
considerations.
2017-06-30 16:28:28 -07:00
Tyler Veness
0cd03c66e3 Remove deprecated Task class (#550) 2017-06-30 16:12:19 -07:00
Thad House
462b231dac Adds function to HAL to free malloc'd joystick name (#543)
No safe way to do this with interop, so a function is needed.
2017-06-30 16:11:16 -07:00
Tyler Veness
e4a918850f Fixed return value of SendableChooser<T>::GetSelected() for non-pointer T's (#512)
Fixed undefined behavior when returning nullptr for T = std::string. Also added
support for smart pointers. T = std::unique_ptr<U> returns U* and T =
std::shared_ptr<U> returns std::weak_ptr<U>.
2017-06-30 15:37:22 -07:00
Thad House
d472af3517 Removes CAN.h from the HAL (#556)
I can't find where the actual code is implemented, and I get errors if I
try to link or compile to any of its functions. Even CANJaguar doesn't
use them, nor did the old impl of CANTalon. Plus looking at the API it
makes no sense anyway, since it doesn't do any buffers , so I think its
worth it to remove it.

Removes CAN.h from the JNI header
2017-06-30 15:13:51 -07:00
Tyler Veness
98a587a347 Removed unused includes and added missing stdint.h includes (#549) 2017-06-25 09:05:49 -07:00
Aaron Pinto
5fd996876b Fixed a typo (#547) 2017-06-04 00:34:11 -04:00
Tyler Veness
b433d98c02 Replace std::stringstream with llvm::raw_svector_ostream (#345)
A few locations were changed to use std::ostringstream.
2017-05-15 23:10:40 -07:00
Thad House
7006672b06 Fixes hal shim from alias to using item (#538)
Fixes #536
2017-05-12 17:02:54 -07:00
Thad House
efec0c5cc3 Moves the HAL priority_ custom types to the hal namespace (#532)
There is a shim for backwards compatibility, just like the frc namespace.
As with the frc namespace, the library compiles without the shim.
2017-05-11 21:25:22 -07:00
Thad House
16e71eac43 Fixes assertions to not crash StringRef (#534)
We can't read [0] on an empty StringRef or the StringRef itself asserts
(this may crash in non-debug mode as an empty StringRef is not guaranteed to have a valid pointer).
Instead, we can just check if the StringRef is not empty.

Closes #502
2017-05-10 20:14:14 -07:00
Thad House
68b62abb52 Adds chrono wrapper around fpga time (#527)
Useful for some of the scenarios in C++ where using the chrono wrappers
might be very helpful.
2017-05-09 20:29:29 -07:00
Thad House
b2f3479692 Switches SPI and I2C to use enums in the HAL for ports (#531)
Closes #397
2017-05-09 12:12:46 -07:00
Tyler Veness
67d62ba164 Travis now passes the current year to wpiformat (#438)
See also styleguide#41.
2017-05-08 21:56:35 -07:00
Thad House
e1fc60b8dd SolenoidBase functions are now static (#530)
Instance methods were kept around for backwards compat in Java. In C++,
the instance methods were changed to match Java. Also some cleanup to
the JNI layer to match updated variable types we missed.

Closes #416
2017-05-08 21:55:11 -07:00
sciencewhiz
f32e696fef Fix exception when getting a relay in kReverse Direction. Fixes #458 (#525)
Add additional tests that would have caught this previously.
2017-05-08 21:54:03 -07:00
Thad House
fc81298fac Switches DS to use Occur callback rather than internal netcomm semaphore (#510)
Allows us to control multithreaded access and spurious wakeups easier.
closes #509

Switches DS to use new waitForData functionality

Adds a few new functions
2017-05-08 20:21:47 -07:00
Thad House
5987cfeaaf Fix SPIs to not set CS DIO pins into DIO mode (#504)
HAL_GetPort both allocates the DIO and sets the DIO into DIO mode.  The DIO setting was overriding the SPI setting on the port, so SPI chip selects were broken if you had more than one.  Instead use CreatePortHandleForSPI, which is a special function that only allocates the DIO handle, but doesn't actually set the DIO into DIO mode.
2017-05-08 20:04:41 -07:00
Thad House
cd0ece4511 Removes the semaphore class (#529)
Its been deprecated, and its going to interfere with fixing #459
2017-05-08 19:42:28 -07:00
sciencewhiz
dc9f85ebb9 Fix comment refering to old _val enum values (#524) 2017-05-07 17:10:52 -07:00
sciencewhiz
35a2055cda Improve documentation for WaitCommand and TimedCommand. (#494) 2017-05-07 13:29:11 -07:00
Austin Shalit
a1066776a5 Make SmartDashboard methods static (#523) 2017-05-07 10:32:40 -07:00
Austin Shalit
4dae747343 Refactor RobotDrive squaring (#390) 2017-05-07 09:40:48 -07:00
Thad House
d348a5b947 Fixes WaitForInterrupt to return values matching enum (#503) 2017-05-07 09:07:14 -07:00
Austin Shalit
f0c413f40d Relay stores nt value in enum (#460) 2017-05-07 09:05:15 -07:00
Austin Shalit
846eee2f6c HashMap -> LinkedHashMap (#492) 2017-05-06 23:38:10 -07:00
Austin Shalit
0b9ff68da1 StartLiveWindowMode ITables use lambdas (#461) 2017-05-06 23:26:18 -07:00
Austin Shalit
7187e005d4 Add Checkstyle WhitespaceAfter check (#466) 2017-05-06 23:22:16 -07:00
Chris Gregory
a5cd24e7ea Reduce scope of for loop variables to for loop initializer (#517) 2017-05-06 23:15:34 -07:00
Jonathan Leitschuh
dbe821baee Change the wrapper to use the all distribution with the sources (#498) 2017-05-06 21:34:15 -07:00
Peter Johnson
04486c6472 CameraServer: Always update addresses when updating stream values. (#496)
This should prevent (as currently happens) occassionally getting just the
mDNS address in the stream value.
2017-05-06 21:31:45 -07:00
Austin Shalit
2ee8ba9361 SafePWM: Rename Feed to feed (#463)
Add a deprecated shim to avoid breaking any user code using Feed.
2017-05-06 21:31:02 -07:00
Thad House
b07782cd89 Removes StatusIsFatal checks from PDP (#493)
The exceptions were removed from Java because these fail more often then
not. Teams are noticing this in C++ as well. In addition for some reason
ClearErrors() is causing about 0.5 seconds of lag. That's another issue,
but this will match Java and solve that issue for users.
2017-05-06 21:29:32 -07:00
Austin Shalit
305450b6e4 Remove 'value' from PIDSourceType (#464) 2017-05-06 21:27:07 -07:00
Thad House
fdd0b853ed Fixes Base.h to work properly with MSVC 2015 and above (#513) 2017-05-06 21:23:33 -07:00
Max Narvaez
1d025204e7 Fixed Spelling Mistakes in SmartDashboard.java (#506)
Fixed comment spelling.
2017-04-30 00:29:27 -07:00
Tyler Veness
12f759860e Corrects assumptions about return values from i2c-lib (#484)
Fixes #478
2017-02-17 00:05:54 -08:00
Austin Shalit
1bdbb5ddcc Remove usages of isEnable() (#483) 2017-02-14 01:16:36 -08:00
Paul Friederichsen
b573fb6555 Fix param order in RobotDrive docs (#481)
Fix Javadoc @param order in RobotDrive and fix order of params in C++ docs
2017-02-14 01:14:56 -08:00
Thad House
b50a7bdbee Fixes memory leak for SPI reads (#474)
Adds a stack allocation for most use cases.
2017-02-14 01:14:08 -08:00
Thad House
5a5f10dfc8 Fixes I2C read change size of pointer (#479)
Fixes #477
2017-02-10 15:21:59 -08:00
Peter Johnson
e375b4a9ff CameraServer: auto-increment startAutomaticCapture(). (#468)
Also add GetServer() functions so the automatically created VideoSink can
be retrieved by user code if desired.
2017-01-20 01:07:37 -07:00
Thad House
ff141ab1ff Fixes exception on camera creation without plugged in camera (#470)
Would throw if the camera was disconnected. We handle this properly at
the JNI level to not have this crash the entire program, but the error
is still kind of annoying, and not really an error.
2017-01-20 01:02:27 -07:00
Peter Johnson
b8537be219 CameraServer: Remove NT-driven settings. (#467)
Unfortunately, due to the way NT synchronization is currently performed,
this has unexpected and undesirable behavior: when a dashboard (or any other
NT client) is left running between code restarts, when it reconnects, any
code settings will be overwritten by the NT synchronization process.  As
fixing this will require a fairly major NT change (and likely a user-visible
one), it's not desirable to do at this point in the year.

Instead, disable NT driven settings entirely (e.g. make the NT interface
publish only).  To emphasize the read-only nature of the NT values, attempts
to change the NT values will be immediately overridden by CameraServer.

To better inform users about the actual property names (e.g. for use in their
code), the "raw_" settings no longer have "raw_" removed from their names
(they are still placed in the "RawProperty" subtable).

This change also contains a couple of Java fixes:

* Make getInstance() thread-safe

* Properly synchronize access to m_tables between multiple threads.

* Use Hashtable instead of HashMap.
2017-01-19 12:30:07 -07:00
Austin Shalit
8f1b034b2f Fix typo in JavaDoc (#462) 2017-01-16 22:57:28 -07:00
Thad House
71d0a07e0a Fixes solenoid allocation error message (#455)
The error was NO_AVAILABLE_RESOURCES, which is not the proper error to
return. Instead,  just return the error directly from the allocation.
2017-01-14 23:59:05 -07:00
sciencewhiz
d322342494 Remove comments about Blue DS (#450)
It's unlikely that anyone is still using the Blue Kwikbyte DS from 2009,
and the reference is confusing to people who weren't around then.
2017-01-14 23:52:48 -07:00
Peter Johnson
bc7ab17692 CameraServer updates (#446)
* CameraServer: Add properties and video mode NT interchange.

* Automatically serve Axis cameras so they're accessible via USB.
2017-01-05 02:51:55 -08:00
Tyler Veness
7a049c29bd Added a conditional command that chooses 1 of 2 commands (#435)
Tests and documentation for ConditionalCommand were also added. This is a fixed version of #9, so it doesn't support lambdas.

Closes #9
2017-01-04 23:48:13 -08:00
Thad House
1fc375b31a Updates the gradle wrapper to version 3.3 (#445) 2017-01-04 22:08:48 -08:00
Austin Shalit
eee7f3991c Allow VisionRunner to stop (#442) 2017-01-04 19:41:07 -08:00
Thad House
2e3503517d Add OS level serial port (#426) 2017-01-04 19:38:17 -08:00
Austin Shalit
15e58acc76 Java SendableChooser no longer sets a default on addObject (#441) 2017-01-03 19:13:45 -08:00
Austin Shalit
5aa5e3e09e SendableChooser generic value (#433)
* Java SendableChooser now decorates with type (non-breaking change)

* C++ SendableChooser now is templated on the type instead of using void* and stores values (breaking change)

* C++ SendableChooser now uses llvm::StringMap instead of std::map
2017-01-03 14:40:31 -08:00
Tyler Veness
25ae7b2c2b Upgraded Doxygen gradle plugin to 0.3 (#440) 2017-01-02 10:03:37 -08:00
Tyler Veness
4b6dc9583a Corrected order of access specifiers in MockCommand class (#436) 2017-01-02 00:44:35 -08:00
Thad House
64eab1f7b3 Fixes missing Extern "C" from HAL Threads (#437)
Also fixes incorrect return value during set
2017-01-02 00:43:12 -08:00
Thad House
182f57216f Adds project and classpath ignores (#425)
VsCode now supports Java, but it creates these files, and there is no
way to turn it off. Will be adding this to a few other repos too.
2017-01-01 00:08:13 -08:00
Tyler Veness
65b091a39a Call SmartDashboard::init() in RobotBase constructor. (#428)
Fixes #427
2017-01-01 00:07:22 -08:00
Austin Shalit
ed1a94531a Update license headers to 2017 (#434) 2017-01-01 00:05:57 -08:00
Fred Silberberg
4e12ffb0ae Update the wpilib version plugin (#423) 2016-12-25 23:01:03 -08:00
Peter Johnson
4800c201e4 Add Axis camera creation functions and Http camera NT publishing. (#420) 2016-12-24 21:05:08 -06:00
Thad House
dc9a9e5d96 Fixes typo in SensorBase error message (#422) 2016-12-24 21:04:32 -06:00
Thad House
6844f05c3d Adds SetAllSolenoids function to CTRE PCM code (#419)
Closes #417.
2016-12-23 14:35:45 -06:00
Austin Shalit
8f67f2c24c Remove unused code and add pmd check (#395) 2016-12-23 13:20:13 -06:00
Thad House
cc246bb9ac Switches JNI to use new jni_util methods (#404)
* Uses WPIUtil string objects in JNI

* Switches JNI to use new jni_util classes
2016-12-23 13:13:17 -06:00
Sam Carlberg
bf9f0a9e6d Add vision pipeline API to make it easier to run OpenCV pipelines (#388) 2016-12-23 10:48:56 -06:00
Austin Shalit
c3160bad44 Update SendableChooser to use HashMap (#394) 2016-12-22 15:56:23 -08:00
Thad House
94b8ac42ca Adds CPP version of vision pipeline (#399) 2016-12-21 23:58:42 -06:00
Thad House
a03e3d7eb9 Fixes HAL to build without all headers included in HAL.h (#418) 2016-12-21 23:55:31 -06:00
Jaci R
a42ec08d16 Fix RoboRIO Cross-Toolchain GCC Status (#405)
* Dedicated RoboRIO Toolchain, allow Toolchain Path to change

* Add cCompiler Tool to correctly discover RoboRIO GCC on Mac

* Add @333fred requests for GString and ToolChainPath

* Add Toolchain Path option to README
2016-12-21 19:56:28 -08:00
Thad House
fddb6cd9d8 Fixes SPI Accumulator averages (#415) 2016-12-21 20:17:53 -06:00
Thad House
841f016017 Fixes SerialHelper when used with OS serial ports. (#411)
Also makes the SerialHelper API public so it can be used externally.
2016-12-21 00:16:05 -06:00
Thad House
8e4afc95c7 Switches C++ strings to StringRef (#336) 2016-12-21 00:08:24 -06:00
Tyler Veness
8cec948699 Fix typos (#409) 2016-12-19 22:06:39 -06:00
Tyler Veness
31ae7c942c Fixed signatures of deleted assignment operators (#408)
While it technically doesn't matter what the return type of the assignment operator is since it's deleted, assignment operators should return a reference instead of a value.
2016-12-19 11:24:23 -08:00
Tyler Veness
d0900626da Removed format.py shim (#393)
Now that our formatter is a Python package (wpiformat), the format.py shim for invoking it is no longer necessary. styleguide#29 should be merged before this patch.
2016-12-18 19:46:20 -08:00
Peter Johnson
0ee4cadca0 CameraServer: Workaround LabVIEW dashboard OpenCV compatibility. (#406)
The current LabVIEW dashboard (Beta 4) requires the source type to be either
"usb:" or "ip:" and does not support "cv:".  To work around this, use a source
type of "usb:" for OpenCV sources as well.

Workaround for #407.
2016-12-18 13:36:44 -08:00
Thad House
24b5a9c389 Adds UsageReporting include when using the LabVIEW shim (#401) 2016-12-16 22:42:45 -08:00
Austin Shalit
626220e9f3 Fix javadoc typo (#403) 2016-12-15 19:46:42 -08:00
Thad House
323d68d460 Fixes multiple initialization of HAL_BaseInitialize (#400) 2016-12-13 12:31:44 -08:00
Thad House
db2091dd94 Adds safe serial port write methods (#396)
The old method had a fairly large risk of undefined behavior, and the way the docs
were written could cause users to get confused.
Deprecate the old method and add StringRef method as preferred approach.
2016-12-10 22:40:44 -08:00
Thad House
8216d85e52 Adds check for PWM overallocation (#392) 2016-12-09 21:23:54 -08:00
Austin Shalit
a705eb1c61 Add PMD and solve issues (#389) 2016-12-07 21:24:44 -08:00
Thad House
77f664a6b1 Fixes simulator HAL builds (#391) 2016-12-06 19:56:31 -08:00
Austin Shalit
c30057e923 Remove unused imports (#387) 2016-12-05 21:36:52 -08:00
Peter Johnson
06108b9479 Update CameraServer support. (#386)
* Follow MixedCase rename.

* Add GetVideo function to get cameras by name.
2016-12-04 00:26:08 -08:00
sciencewhiz
16181523c9 Put language in version string (#377) 2016-12-02 20:36:22 -08:00
Jacob Caporuscio
7e0706cf83 Updated Usage Reporting for 2017 v8 Image (#385) 2016-12-02 18:16:49 -08:00
Thad House
bff67887fd Adds capabilities to support certain HAL functionality from LabVIEW (#382)
They can only include HAL/LV/HAL.h, HAL/cpp/*.h, and HAL/handles/*.h.
Nothing else will work properly.
2016-12-02 00:32:01 -08:00
Thad House
351ff5eb48 Adds new Threads API for priority setting while using std::thread (#379)
Also adds Java API for doing the same to Java threads (standard Java Thread.setPriority only works
when Java is run as root, even if the process has the right privileges).
2016-12-01 21:06:19 -08:00
Thad House
051df14046 Updates ni patch task to automatically switch all files to LF (#381)
Still requires manual intervention to make files not readonly, but
that's easier.
2016-11-29 20:20:49 -08:00
Thad House
ee0318f697 Updates NI Libraries to image 8 (#380) 2016-11-29 19:56:30 -08:00
Thad House
a6fb1efcbe Switches internal joystick errors to take StringRef (#378)
Previously this would have allocated the std::string every time, even if
the message wasn't printed. Now takes a StringRef, and only converts to
std::string when the message actually gets printed.
2016-11-26 21:22:39 -08:00
sciencewhiz
31fecc28a4 Check for NaN motor speed. Fixes artf5467. (#376) 2016-11-26 21:04:40 -08:00
Thad House
30b1efc354 Adds check to ensure all JNI symbols have been defined properly (#373) 2016-11-25 17:07:36 -08:00
Thad House
7d721eb569 Fixes memory leak in SerialHelper VISA (#366) 2016-11-25 15:52:21 -08:00
Fred Silberberg
d48aac5beb Gradle Update (#372)
This does a major cleanup on our gradle files, primarily converting all instances of manual dependency downloading to use the correct configuration-based method, which has the advantage of being both less code and more safe.
2016-11-24 23:44:35 -08:00
Fred Silberberg
14b56db99e Gradle 3.2.1 (#369)
Updated to gradle 3.2.1. This also moves all of the task graph listeners for dependency setup to use the gradle model, making it both safer and reducing line count.
2016-11-24 22:15:54 -08:00
Thad House
bfe429de51 Switches handles back to std::array (#367)
The binary size is being increased much less then when we originally
tried this. Using static arrays save a pointer indirection and will help
with cache in real time cases.
2016-11-24 21:55:20 -08:00
Thad House
57ef5cfd07 Splits out SerialHelper to allow using OS or VISA resources (#365)
Also removes regex and uses simple splits instead
2016-11-24 21:53:04 -08:00
Fred Silberberg
4bbb7c0bcc Fixed javadoc generation to actually download cscore and ntcore and include the source in its output. (#368) 2016-11-24 21:51:01 -08:00
Thad House
4de70bff5e Adds missing JNI method definitions (#371) 2016-11-24 21:49:34 -08:00
Peter Johnson
687f0c7dc0 Use const parameters in std::sort lambda. (#364)
This is more correct, and non-const fails on gcc 4.8.
2016-11-22 22:30:58 -08:00
Thad House
f3d66e92ec Searches for USB serial devices to get the correct VISA object (#363)
Fix was made in LabVIEW, and this matches what was done there.
2016-11-22 21:51:47 -08:00
Thad House
9a91ae54d6 Fixes incorrectly changed Java enums (#360)
Some enums need a specific value when they get passed to JNI
2016-11-20 20:32:52 -08:00
Tyler Veness
69422dc063 Replaced floats with doubles (#355)
This makes our APIs more consistent. With optimizations enabled, doubles are just as efficient as floats on ARMv7, so we should take advantage of the extra precision.
2016-11-20 07:25:03 -08:00
Dustin Spicuzza
7bcd243ec3 Reorder the HAL handle types (#357) 2016-11-20 00:01:24 -08:00
Thad House
8f70bea899 Fixes Athena Runtime build not including ntcore (#356) 2016-11-19 23:58:29 -08:00
Thad House
948c4275ad Fixes the wpilibj jar not getting updated during every build (#359) 2016-11-19 23:52:19 -08:00
Peter Johnson
03a1159915 Java CameraServer: Fix type cast exception. (#358)
Also fixes an unchecked warning.
2016-11-19 22:45:45 -08:00
Tyler Veness
1c8fb298b4 Ran formatter (#354) 2016-11-19 00:39:32 -08:00
Tyler Veness
b25a7cb370 Command::IsFinished() must be overriden by subclasses again (#353)
Documentation was added for InstantCommand and TimedCommand.
2016-11-19 00:26:22 -08:00
Tyler Veness
140c365e4b Added XboxController class (#140)
Joystick and Gamepad functionality was separated into cleaner interfaces.
2016-11-18 23:05:37 -08:00
Peter Johnson
8c93ceb728 Add cscore-based CameraServer. (#352)
Not fully functional yet, but implements basic functionality required for LabView dashboard interoperability.
2016-11-18 22:30:22 -08:00
Thad House
ac50d7cf8a Removes NiVision from allwpilib (#305) 2016-11-18 20:04:21 -08:00
Thad House
ecb873ff45 Fixes myRobotJava zipping before Java gets built (#351) 2016-11-18 19:44:13 -08:00
Thad House
78baa04ecc Adds OpenCV to myRobotJava (#350) 2016-11-18 16:20:30 -08:00
Krypton Cougars
b78f580d47 Adds default methods for Commands (#238) (#238)
Closes #235
2016-11-18 14:42:40 -08:00
Thad House
b115c75226 Adds SPI DIO to WPILib (#256) 2016-11-18 14:15:53 -08:00
Thad House
6bc092f3ae Updates SPI device pin (#348) 2016-11-18 14:14:51 -08:00
Thad House
f99a266ce4 Adds CsCore dependency to myRobotCpp (#349) 2016-11-18 14:14:11 -08:00
Fred Silberberg
1f724d58e0 Made the test scripts executable to fix -dirty on the version numbers. (#347) 2016-11-14 21:16:51 -08:00
Thad House
de4a246bb4 Adds OpenCV Loading to wpilib program startup (#338) 2016-11-11 22:32:13 -08:00
rrossbach
412b80da30 Fixes joystick button handling HAL JNI layer (buttons are in an (#341)
int, not a byte)
2016-11-10 20:21:54 -08:00
Thad House
47319960a5 Fixes a missed change to unique_ptr in the HAL (#337) 2016-11-08 16:53:17 -08:00
Thad House
b22d218236 Removes CANJaguar specific constants from JNI files (#339) 2016-11-08 16:52:24 -08:00
Thad House
6eb82bc314 Exclude genlinks.bat from HAL zip (#333) 2016-11-06 21:47:34 -08:00
Thad House
a06dd25d56 Adds cscore and opencv to wpilib (#332)
Unit tests now run using shared wpilib as well, since we had to add a ton
of sharedl ibraries anyway. Test scripts also updated to work properly.
2016-11-06 21:47:18 -08:00
Thad House
e1bb05bc52 Updates to the 2017 v7 image (#329) 2016-11-05 23:20:40 -07:00
Tyler Veness
8694a020ac Removed entries from .styleguide that are included in .gitignore (#331)
format.py now considers files that match patterns in .gitignore to be modifiable files. Therefore, listing them in .styleguide is redundant.
2016-11-05 08:39:46 -07:00
Thad House
1efb2e4d3d Deprecates Task and Semaphore, and changes other deprecations to use wpiutil version (#330) 2016-11-05 00:23:52 -07:00
Thad House
861726cefa Adds gradle task to fix NI libraries whenever new ones are added. (#325)
Generates genlinks, and modifies headers to make them self contained
2016-11-04 15:17:17 -07:00
Thad House
81212d80c6 Fixes ultrasonic declaration (#328)
Also adds test to ensure this doens't happen again
2016-11-04 15:02:29 -07:00
Thad House
2235a809c4 Fixes a missed change from the ni-libraries location change (#326) 2016-11-04 13:26:34 -07:00
Thad House
3fe0f49ac0 Moves NI headers to their own folder in the repo (#324) 2016-11-04 01:22:28 -07:00
Thad House
03d8f9193b Moves using namespace from ChipObject.h into hal namespace (#323) 2016-11-03 23:01:13 -07:00
Thad House
5e54969f6b Adds Task back into WPILibC (#320)
Note that deprecation has not been added yet, since we need to add the
deprecation API's for MSVC and GCC < 4.9.
2016-11-02 22:17:40 -07:00
Thad House
18ef5eb1bf C++ and Java tests for the new build system (#309) 2016-11-01 23:41:05 -07:00
Tyler Veness
b5e3d92e9d Remove errant "using namespace" in global namespace (#318) 2016-11-01 23:40:28 -07:00
Tyler Veness
ba8761e39e "using" directives are no longer used in global namespaces (#219) 2016-11-01 23:09:51 -07:00
Thad House
78f0b1562c Removes Task.h from wpilib.h header (#317) 2016-11-01 23:08:57 -07:00
Thad House
5c28b30028 Removes NetworkTables from Java executable jar (#303) 2016-11-01 22:34:52 -07:00
Peter Johnson
59267da72b Namespace all wpilibc functions/classes into "frc" namespace. (#311)
Base.h provides a backwards compatibility shim (enabled unless
NAMESPACED_WPILIB is defined) that does a "using namespace frc".
However, as some header files do not include Base.h, this may
be a breaking change in some corner cases (with an easy fix).

Fixes #218.
2016-11-01 22:33:12 -07:00
Dustin Spicuzza
36ad45c07d Delete .gitreview (#316) 2016-11-01 22:31:53 -07:00
Thad House
ecb2add791 Removes additional references to CANTalon from the library. (#312) 2016-11-01 20:13:26 -07:00
Thad House
9bbdaf300b Removes the task class from wpilib (#314)
Was required back on the cRIO, but there are much better alternatives
nowadays.
2016-11-01 20:12:08 -07:00
Thad House
bc492bb40e Removes the REAL definition from wpilib.h (#315)
Interferes with OpenCV, and is heavy namespace polution anyway.
2016-11-01 19:23:59 -07:00
Thad House
81221c4874 Moves JNI internal utility methods to frc namespace (#310) 2016-10-31 23:04:49 -07:00
Thad House
137b3d81fb Fixes JNI file not being copied to output directory for integration tests (#308) 2016-10-30 23:14:19 -07:00
Fred Silberberg
6741f47ef1 Update version plugin (#307) 2016-10-30 01:18:18 -07:00
Thad House
e75e9092a8 Fixes athena runtime zip not being built at the correct times (#306) 2016-10-27 22:01:28 -07:00
Thad House
247cef5ec2 Removes CANJaguar from wpilib (#300)
Now located at https://github.com/wpilibsuite/CANJaguar.
2016-10-27 10:54:52 -07:00
Thad House
29f999e2b2 Adds new handle structure and type for vendors (#297) 2016-10-26 23:09:33 -07:00
Thad House
5e3755493d Linking and maven publish location rewrite (#298)
* Links HAL shared instead of static, and doesn't include library in jar

* Strips shared object files, and includes debug in releases

* Zips the HAL libraries into a separate maven artifact

* Switches to shared wpiutil

* Switches wpilibc to shared

* Moves maven artifacts

wpilibc now in edu.wpi.first.wpilibc:athena
wpilibj now in edu.wpi.first.wpilibj:athena
wpilibj jni not in edu.wpi.first.wpilibj:athena-jni
hal now in edu.wpi.first.wpilib:hal
athena runtime added (hal, ntcore, wpiutil) edu.wpi.first.wpilib:athena-runtime

Changes made where wpilibc does NOT include all required artifacts anymore. Dependent on hal, wpiutil and ntcore packages to work correctly.
JNI does NOT include all required artifacts anymore. Dependent on hal and wpiutil packages to work correctly.
2016-10-25 20:46:09 -07:00
Thad House
70343c0b3f Fixes missing function for Timer::GetMatchTime() (#299) 2016-10-25 19:01:18 -07:00
Thad House
60e199b0bd Fixes format.py on windows (#293) 2016-10-24 22:17:02 -07:00
Thad House
1071686d81 Replaces C++ IsNewControlData semaphore with atomic bool, and Java code with AtomicBool (#187) 2016-10-24 20:32:43 -07:00
Tyler Veness
fdebdd520a Added format.py to Travis config (#236) 2016-10-23 21:37:43 -07:00
Tyler Veness
5ca5583fc3 Removed unnecessary set of parentheses and ran formatter (#290) 2016-10-23 16:34:00 -07:00
Thad House
75463a249f Implements threaded notifiers and interrupts in the HAL (#281) 2016-10-23 14:34:43 -07:00
Thad House
7280d241f0 Fixes DIO not erroring with too high of DIO number (#288) 2016-10-23 14:21:14 -07:00
Austin Shalit
963391cf39 Cleanup SolenoidBase, Solenoid, and DoubleSolenoid (#271) 2016-10-23 14:20:28 -07:00
Thad House
4f4c52d6d5 Switches JNI to use SafeThread from WPIUtil (#282) 2016-10-23 14:18:46 -07:00
Fred Silberberg
499da6d08d Updated the wpilib version plugin to 1.2. Fixes issues with submodules. (#289) 2016-10-23 14:17:59 -07:00
Austin Shalit
39e4d11f8e Remove .pullapprove.yml (#287) 2016-10-23 11:20:29 -07:00
Thad House
df4a2c07f0 Checks for system initialization in functions that can be called before creating handle based objects (#285) 2016-10-23 10:00:34 -07:00
Thad House
c46c490376 Adds wpiUtil to HAL and JNI (#280) 2016-10-23 09:51:30 -07:00
Thad House
f2751db5c2 Adds NI Libraries symbolic link (#286) 2016-10-22 14:21:26 -07:00
Thad House
2bff276adb Fixes a missed formatting issue (#283) 2016-10-21 08:30:49 -07:00
Fred Silberberg
e5e1a1a4d1 Moved version generation to the WPILib versioning plugin. (#277)
* Moved version generation to the WPILib versioning plugin. This also moves ntcore and wpilib to the latest available version.

* Fixed description string.

* Gave full path for ignored files.
2016-10-20 23:54:04 -07:00
Austin Shalit
0613f1d182 Cleanup encoder class (#272) 2016-10-19 22:39:47 -07:00
Austin Shalit
8b94e0933a Update README (#261)
Update the README to include instructions on how to image the test bench roboRIO.
2016-10-19 22:37:43 -07:00
Austin Shalit
23ef57561d Cleanup PowerDistributionPanel (#275) 2016-10-19 22:34:57 -07:00
Austin Shalit
33b95816ee Cleanup SensorBase class (#273) 2016-10-19 22:33:36 -07:00
Thad House
4c1e4fd80c Updates image to v6 (#278)
Added exports of the environment variables set in the frcRunRobot script to prevent fork calls.
2016-10-19 22:30:29 -07:00
Fred Silberberg
3784b665de Updated version for beta 1 (#270) 2016-10-13 18:50:39 -07:00
Kevin-OConnor
567ea1d58d Remove CAN TalonSRX from WPILib (moving to external library) (#268) 2016-10-13 18:50:20 -07:00
Austin Shalit
55346e28d0 DoubleSolenoid free reverse port handle instead of channel (#274) 2016-10-13 12:41:36 -07:00
Fred Silberberg
49b8c4ba78 Fixes the gradle dependencies for building (#269) 2016-10-12 21:06:33 -07:00
Thad House
f1c2b66569 Reverts the 2017 Image for Beta 1 (#264)
* Revert "Updated the rpath to point to the correct location for the Java integration tests. (#262)"

This reverts commit c313dde03a.

* Revert "Update image 2017 v5 (#254)"

This reverts commit 8d1c51b7e9.
2016-10-12 19:52:49 -07:00
Austin Shalit
27bf94fd06 Remove kDefaultPeriod from IterativeRobot (#232)
* Remove kDefaultPeriod from IterativeRobot

* Remove period

* Remove NextPeriodReady
2016-10-09 13:58:30 -07:00
Thad House
4896a77c86 Fixes guarantees for waitForData (#252)
As discussed in #234, we now check for the timeout case and handle a
timeout correctly.
2016-10-09 11:46:01 -07:00
Austin Shalit
d1d3f049f2 Solve scp file not found (#263)
Solves the scp file not found bug after installing a new image on the test bench.
2016-10-09 11:45:26 -07:00
Fred Silberberg
c313dde03a Updated the rpath to point to the correct location for the Java integration tests. (#262) 2016-10-08 13:08:26 -07:00
Fred Silberberg
8d1c51b7e9 Update image 2017 v5 (#254)
* Updated the image version and dependent libraries to 2017 v5.

* Updated version for beta 1

* Some additional library updates, task updates, and rpath updates
2016-10-08 00:13:31 -07:00
Thad House
a59e00e901 Adds a test to make sure WaitForData is properly waiting (#258) 2016-10-06 11:18:47 -07:00
Tyler Veness
7070162b98 Fixed lint errors (#259) 2016-10-06 11:05:09 -07:00
Thad House
9859c14ca1 Fixes status parameter in wrong location for initialization range functions (#260) 2016-10-06 11:04:38 -07:00
Thad House
64ebe7f5e5 Updates SmartDashboard with new NetworkTables3 functions (#162) 2016-10-03 09:59:18 -07:00
Thad House
8b2345a706 Removes an unnecessary function from HAL Power (#237)
Was not declared in header, so never used anywhere
2016-10-03 09:52:47 -07:00
Thad House
e65f9908d7 Makes IterativeRobot not double check for new control data (#253)
Previously could cause a race condition. Also moves wait to the top of
the loop in order to avoid having an initial loop be ran before data can
be check.

Sim is handled in #232, except that needs to be updated as well to move
the wait to the top of the loop.
2016-10-02 09:05:32 -07:00
Tyler Veness
fd52912d74 Fixed return value propagation of format.py (#251) 2016-10-02 08:10:22 -07:00
Fred Silberberg
9e7993905f Remove slack integration (#257)
Slack integration is useless noise that no one reads. This removes it.
2016-10-02 01:11:09 -07:00
Thad House
a656207220 Forces exceptions to throw on HAL handle creation functions (#209)
Fixes #199
2016-09-29 20:18:40 -07:00
Peter Johnson
81e63ea3a5 Fix simulation build with latest ntcore/wpiutil. (#250) 2016-09-28 20:45:03 -07:00
Tyler Veness
5dfae8d6bd Fixed include order (#245)
See wpilibsuite/styleguide (#11).
2016-09-25 16:50:13 -07:00
Peter Johnson
107a4cc1e2 Add wpiutil dependency. (#190) 2016-09-25 16:47:49 -07:00
Tyler Veness
35d51d68f7 Made a comment use more professional language (#249) 2016-09-23 22:16:33 -07:00
Tyler Veness
049fec470b Fixed compilation with GCC 6 (#248)
Since newer versions of GCC emit more warnings and errors, I tried building WPILib with GCC 6.2.0. This patch fixes compilation errors that occurred.
2016-09-23 20:27:11 -07:00
Tyler Veness
659dbef751 Ran format.py after writing unit tests for and fixing bugs in it (#239) 2016-09-21 23:48:54 -07:00
Tyler Veness
ac9b6f7b18 Implemented CircularBuffer resizing (#224) 2016-09-20 19:43:34 -07:00
Tyler Veness
425ed464ed Removed leading underscores from variable names (#246) 2016-09-20 12:41:42 -07:00
Austin Shalit
2c15bb247e Remove delay from periodic methods. (#243) 2016-09-20 12:34:17 -07:00
Austin Shalit
28e178b1a8 Update Compressor documentation (#244) 2016-09-20 12:31:16 -07:00
sciencewhiz
5d2a08443b Fix Typos. Fixes artf4853 (#242) 2016-09-18 08:43:22 -07:00
Tyler Veness
087eeec760 C standard library functions and types are now prefixed with std:: (#227) 2016-09-14 20:52:06 -07:00
Thad House
dbe03afb9a Fixes error in driver station control word cache (#222) 2016-09-13 21:22:25 -07:00
Thad House
2ecb939b35 Add a method to detect the HAL runtime version (#228) 2016-09-13 21:21:57 -07:00
Austin Shalit
1416fb8f67 Update Periodic JavaDoc (#231) 2016-09-13 21:21:25 -07:00
Tyler Veness
aeb6c4889b Added license template file (#225) 2016-09-13 20:28:07 -07:00
Thad House
c2fc6711d8 Switches enums to use a fixed size for their base (#230) 2016-09-13 20:27:38 -07:00
Thad House
f271185cbc Adds a RobotPeriodic method to IterativeRobot (#226)
Called globally during each IterativeRobot loop
2016-09-13 20:25:18 -07:00
Thad House
4fc7daedc9 Fixes incorrect deadband value being passed over PWM (#223) 2016-09-09 15:58:38 -07:00
Tyler Veness
6bfc008673 Replaced snake case variable names with mixed case (#221) 2016-09-06 19:43:24 -07:00
Tyler Veness
2c94d0ba2f Cleaned up integer type usage in the HAL (#192)
Replaced all uses of built-in types except char with stdint.h typedefs and all unsigned types with signed in the HAL
2016-09-06 19:39:28 -07:00
Tyler Veness
0cd05d1a42 Cleaned up integer type usage in wpilibc (#92)
Replaced all unsigned types to signed and int32_t with int in wpilibc
2016-09-06 00:01:45 -07:00
Tyler Veness
ff93050b31 Remove static_assert for sizeof(uint32_t) <= sizeof(void*) (#220)
According to #192, we don't cast integers to pointers anymore. The size static_assert is unnecessary.
2016-09-05 23:31:58 -07:00
Tyler Veness
05626cfafe Fixed cpplint.py warnings (#215)
* Fixed cpplint.py [build/include_order] and [build/include_what_you_use] warnings
* Fixed cpplint.py [readability/casting] warnings
* Updated .styleguide format
* Fixed cpplint.py [build/header_guard] warnings
2016-09-05 13:55:31 -07:00
Thad House
59ec54887d Switches notifier to use a typedef for the callback, and prepends HAL_ to InterruptHandlerFunction (#216) 2016-09-05 07:31:51 -07:00
Tyler Veness
028efff50d Ran format.py (#217) 2016-09-05 07:31:02 -07:00
Tyler Veness
2499771cf4 Added extensions to .styleguide (#214)
wpilibsuite/styleguide is going to use extensions specified in .styleguide instead of hardcoded extensions. This patch should be merged first to maintain correct operation.
2016-09-01 20:31:38 -07:00
Fred Silberberg
c989ae808b Updated gradle to 3.0 (#208) 2016-09-01 20:30:37 -07:00
Tyler Veness
93b486b6ba Replaced C-style casts found by GCC in HAL, wpilibc, and JNI (#211) 2016-08-24 21:39:16 -07:00
Thad House
2ec6132fcb Switches compiler from -O0 to -Og (#197)
Should be a heavy increase in performance
2016-08-21 19:15:58 -07:00
Thad House
8aba2b2850 Adds .vscode to styleguide ignore files (#210) 2016-08-21 12:35:58 -07:00
Tyler Veness
32c95fa0da Moved style guide documents and scripts to wpilibsuite/styleguide (#207) 2016-08-21 10:31:43 -07:00
Thad House
40365faeda Adds a static mutex to notifiers to stop destructor race condition (#204) 2016-08-15 19:56:32 -07:00
Thad House
776cb915bc Revert "PIDController queue now stores inputs instead of errors (#138)" (#205)
This reverts commit 7501ae65a1.
2016-08-13 23:49:31 -07:00
Thad House
5e9fe2f5cb Adds an ignore for Visual Studio Code files (#203) 2016-08-13 14:44:10 -07:00
Tyler Veness
7501ae65a1 PIDController queue now stores inputs instead of errors (#138)
Closes #29.
2016-08-12 22:04:44 -07:00
Peter Johnson
63469c00c4 run-tests-on-robot.sh: Save coredump on crash. (#201) 2016-08-12 19:18:48 -07:00
Fred Silberberg
3df257cdbb Set duplicate strategy for all jars and zips to prevent duplicates from occurring (#191) 2016-08-12 13:45:58 -07:00
Tyler Veness
45b8e9ab4f Renamed "pin" to "channel" and variables with underscores now use mixed case (#194) 2016-08-12 13:45:28 -07:00
Tyler Veness
227fdc1a60 Updated C++ style guide (#196)
include guard section now requires #pragma once, enumerators now exclusively use constant naming, and a mention of format.py was added to the "Formatting" section and CONTRIBUTING.md.
2016-08-12 07:14:49 -07:00
Tyler Veness
d347cebf67 Cleaned up odd formatting from static_cast by using "u" integer literal (#200) 2016-08-12 06:08:57 -07:00
Tyler Veness
3819cd0768 Updated cpplint.py and fixed its regexes for C-style casts (#193)
Additional C-style cast warnings thrown were also fixed.
2016-08-11 23:38:45 -07:00
Tyler Veness
e8f1fdda44 format.py now emits warnings for modified generated files (#195) 2016-08-11 23:10:10 -07:00
Tyler Veness
fd4719cb87 Fixed Doxygen comments for LinearDigitalFilter (#198) 2016-08-11 22:47:51 -07:00
Tyler Veness
6ef4745d86 Added Joystick::GetAxisType() (#98) 2016-08-07 10:19:19 -05:00
Thad House
62a980d3c8 Fixes Relay Constant Test (#189) 2016-07-26 13:53:45 -07:00
Thad House
866046edd1 Some general cleanups in the HAL (#188)
AnalogTrigger initialization checks are now in the correct order. Plus
frees no longer grab the structure if it is not needed.
2016-07-25 23:26:34 -07:00
Fredric Silberberg
8ac7e44f19 Updates gradle to 2.14.1 (#186) 2016-07-25 21:21:34 -07:00
Thad House
a831978cce Uses the fixed SensorBase functionality in the WPILib (#185) 2016-07-21 23:24:06 -07:00
Thad House
8da577b56f Moves FRCDriverStation to athena folder (#184) 2016-07-21 23:22:02 -07:00
Thad House
512ecf6490 Makes SensorBase checks use HAL check methods (#182) 2016-07-20 22:47:29 -07:00
Thad House
0901ae0808 Switches the HAL structs to use unique_ptr (#183) 2016-07-20 22:05:17 -07:00
Thad House
1ca291f20b Fixes a missed HAL_Bool change from int32 (#181) 2016-07-17 20:54:39 -07:00
Thad House
75eabfee1c Moves DriverStation HAL code to its own header and definition (#179)
To allow for future use as a plugin for the HAL simulator.
2016-07-17 19:42:33 -07:00
Tyler Veness
f7c3f13a7f Improve CircularBuffer documentation (#180) 2016-07-16 20:50:19 -07:00
Tyler Veness
57efd13f7f Replaced PIDController::Initialize() with delegating constructors (#178) 2016-07-16 12:50:17 -07:00
Thad House
7ddc153623 Fixes analog gyro casting to float then returning double (#177) 2016-07-15 18:13:51 -07:00
Tyler Veness
f9ebd3bde6 Fixed PIDController::GetError() for continuous inputs (#169)
Closes #31
2016-07-15 13:44:04 -07:00
Thad House
2c911b0f7a Adds a maximum time based cache to HALControlWord data (#158)
This is one of the calls with the delayed IPC. In the past, teams have
called an IsMode function so much that their code would start lagging.
This adds a cache, so the data is updated either when new data arrives
and we are notified of it, or after 50ms has passes since the last time
the cache was checked and updated.
2016-07-15 13:39:26 -07:00
Tyler Veness
1bf2d58db1 Reordered DriverStation functions in wpilibc and wpilibj to match wpilibc header (#166) 2016-07-14 20:50:38 -07:00
Tyler Veness
c93b5bedf9 Miscellaneous cleanups for wpilibc PID controller (#175)
* Reorder wpilibc PIDController's SetAbsoluteTolerance() and SetPercentTolerance() implementations to be consistent with header and wpilibj

* Added std:: prefix to fabs() calls in wpilibc PIDController
2016-07-14 13:51:32 -07:00
Thad House
dffaa0abb9 Moves HAL cpp headers from root to HAL directory (#174)
Could not include the ctre and NetComm folders, as those would require
changing ctre dependancies. Also removes a duplicated FRCComm header
that was not needed.
2016-07-14 00:17:29 -07:00
Tyler Veness
20c6525b1d Cleaned up wpilibj enums (#167)
* Converted enumerated constants in wpilibj to enums and made their implementation more consistent

* Reflowed text in JNI calls and updated JNI signatures
2016-07-13 23:39:58 -07:00
Fredric Silberberg
fe7165a8f7 Removed double-add of shared classpath. Fixes #157. (#164) 2016-07-13 22:20:30 -07:00
Thad House
d2aa168f66 Implements Better Error Messages from the HAL (#172)
* Makes the HAL provide a better error message for certain things.

* Makes Java error messages better

* Updates C++ errors.

* Moves handles header folder to HAL directory
2016-07-13 20:29:28 -07:00
Thad House
05c00430b3 Fixes CPP lint errors added to HAL. (#173) 2016-07-13 20:16:45 -07:00
Thad House
5305087162 Fixes a missed float to double change in the HAL. (#176) 2016-07-13 19:25:57 -07:00
Tyler Veness
6251697f60 Added Lint task and parallelized format.py (#161) 2016-07-12 21:59:09 -07:00
Thad House
ea1a1e6bc3 Makes the CANJaguar error status messages more useful (#165)
The previous version would just return the class name for the
DigitalOutput port. Now it actually gets the dio port value for better
readability.
2016-07-12 21:53:51 -07:00
Thad House
edf5ecd4a0 Changes HAL Headers to be C compliant. (#171) 2016-07-12 21:53:06 -07:00
Tyler Veness
1b1ee7f9f3 Renamed spiGetSemaphore() to spiGetMutex() (#170) 2016-07-12 15:11:41 -07:00
Tyler Veness
3fade171f9 Fixed inconsistencies in documentation (#168) 2016-07-12 10:50:21 -07:00
Tyler Veness
c99e89dfca Fixed the remaining cpplint.py warnings (#160)
Replaced std::sprintf in BaeUtilities.cpp with std::stringstream and marked GetVisionErrorText() in FrcError.cpp as NOLINT
2016-07-12 10:46:34 -07:00
Thad House
b51e85ae26 Switches HAL to fixed length signed integers, and adds our own HAL_Bool Type (#155)
* Switches HAL to fixed length signed integers, and adds our own HAL_Bool type

* Replaces HAL Floats with Doubles

Doubles are just as fast as floats with optimizations turned on, so
switches to all doubles. All made doubles for consistency.

* Prepends HAL/ to HAL include files. Also fixes some range errors
2016-07-12 10:45:14 -07:00
Thad House
4a98e68815 Moves the DS new data wait calls down to the HAL. (#156) 2016-07-10 23:10:05 -07:00
Tyler Veness
0cb288ffba Fixes warnings thrown by cpplint.py (#154)
* Fixed cpplint.py [runtime/int] warnings

* Fixed cpplint.py [readability/casting] warnings

* Fixed cpplint.py [readability/namespace] warnings

* Fixed cpplint.py [readability/braces] warnings

* Fixed cpplint.py [whitespace/braces] warnings

* Fixed cpplint.py [runtime/explicit] warnings

* Fixed cpplint.py [runtime/printf] warnings

* Fixed cpplint.py [readability/inheritance] warnings

* Fixed cpplint.py [whitespace/tab] warnings

* Fixed cpplint.py [build/storage_class] warnings

* Fixed cpplint.py [readability/multiline_comment] warnings

* Fixed cpplint.py [whitespace/semicolon] warnings

* Fixed cpplint.py [readability/check] warnings

* Fixed cpplint.py [runtime/arrays] warnings

* Ran format.py
2016-07-10 17:47:44 -07:00
Tyler Veness
e44a6e227a Refactored wpilibj HAL JNI to simplify generating it from HAL headers (#109)
wpilibj FRCNetworkCommunication.java is now generated from HAL headers and was renamed to FRCNetComm.java
2016-07-10 16:24:57 -07:00
Tyler Veness
aafca4ed7f Reduced duplication between formatting scripts with Task base class (#80)
Also added scripts for EOF newline management and for removing trailing whitespace. configure.bat was rewritten to use CRLF line endings. Documentation for the existing scripts was also improved.
2016-07-10 08:33:27 -07:00
Thad House
ea6876e81f Some general HAL cleanups (#153) 2016-07-09 17:38:18 -07:00
Tyler Veness
aa9c2b2c92 Made Log.h use std::chrono (#136) 2016-07-09 16:58:31 -07:00
Thad House
43a2eccdc9 Finishes Prefix Renames (#152) 2016-07-09 01:12:37 -07:00
Thad House
b637b9ee4c Prepends all HAL functions with HAL_ (#146) 2016-07-09 00:24:26 -07:00
Thad House
5ad28d58ec Switches PWMs to do scaling at the HAL level. (#143) 2016-07-08 21:29:29 -07:00
Thad House
be2647d44e Switches Java to use HAL Constants (#145) 2016-07-08 00:08:07 -07:00
Thad House
4a3e3a6324 Changes DigitalSource API for HAL ease of use (#144) 2016-07-07 21:43:55 -07:00
Thad House
7597e3c274 Switches handle resources to dynamic arrays (#142) 2016-07-07 21:32:41 -07:00
Thad House
0a983eeeb8 Moves Gyros to the HAL (#131) 2016-07-07 21:31:45 -07:00
Austin Shalit
b036bf2e34 Add method to get the port number of a Joystick (#137) 2016-07-04 09:18:28 -07:00
Tyler Veness
73602e6cb4 Added missing include for robot startup macro (#135) 2016-07-03 23:24:56 -07:00
Thad House
72455280a9 Removes unneeded resource includes from WPILibC files (#134) 2016-07-03 23:18:45 -07:00
Thad House
ea95bb85aa Adds Constants from new constants class to encoders (#133) 2016-07-03 21:52:49 -07:00
Thad House
fb865d3ee7 Adds a special exception and status message for a handle error (#127) 2016-07-03 17:27:06 -07:00
Thad House
36ac37db8c Moves Encoders to Handles and Moves WPILib Encoders to HAL (#124) 2016-07-03 15:22:22 -07:00
Thad House
b45e0917ae Adds port constants to the HAL (#130) 2016-07-02 23:19:14 -07:00
Thad House
0e127679c1 Removes some unused variables from DigitalInternal (#128) 2016-07-02 16:33:19 -07:00
Fredric Silberberg
2f36d508c4 Gradle 2.14 (#118)
Updates the gradle version to 2.14. In doing so, some model elements have changed. Additionally, some redundant elements have been removed from the gradle scripts.
2016-07-02 16:32:14 -07:00
Thad House
cf29d4560b Moves HAL PCM objects to header and HAL namespace (#129) 2016-07-02 11:58:49 -07:00
Thad House
8c4ad62422 Switches Solenoids to Handles (#126) 2016-07-02 09:24:54 -07:00
Thad House
62c217cd01 Switches compressor to handles (#125) 2016-07-02 08:22:44 -07:00
Thad House
0f105a26f7 Switches Counters to Handles (#123) 2016-07-01 00:29:08 -07:00
Thad House
47694ef810 Switches DigitalPWM to Handles (#121) 2016-06-30 23:43:00 -07:00
Thad House
f77a976fbb Switches resource errors to AllocationExceptions in JNI (#122) 2016-06-30 21:39:55 -07:00
Thad House
3593ecb17e Switches PWM and DIO to Handles (#120) 2016-06-30 21:39:09 -07:00
Thad House
9b2af0d090 Switches relays to handles (#119) 2016-06-29 19:58:14 -06:00
Thad House
e8e052712e Switches AnalogInputs and AnalogTriggers to Handles (#117)
Results in a breaking change to AnalogTrigger int constructor. If a user wants
multiple AnalogTriggers, they must use the AnalogInput constructor.
2016-06-27 21:32:30 -07:00
Thad House
77a1af44c4 Removes freePort from the HAL (#116)
It was a no-op, and most likely in the future it will be that way too.
Removing to clean up the API.
2016-06-27 13:38:33 -07:00
Thad House
5e2a76147c Moves handle definitions to main handle header (#115) 2016-06-27 13:36:38 -07:00
Thad House
e1d4845ccd Move Analog Outputs to Handles (#112) 2016-06-27 11:32:40 -07:00
PatrickPenguinTurtle
95d40ed01f Fixed issue with digital outputs used as pwm on mxp (#14)
When a digital output object that was tied to an mxp pin had enable pwm called on it
it would pwm on a pin 6 lower
 (although if this wasn't an mxp pin it wouldn't do anything at all.)
Fixed in Digital.cpp by adding 6 if it is an MXP pin in setPWMOutputChannel()
This should fix the CanJaguar test because when digitalOutputs used as PWM
were freed, the PWM generator was set to the number of pins, which meant it
was actually outputing on pin 20.

Change-Id: Ib48db3e6e3bf78659622145969d24011cc231ea6

Updated Hal to include some documentation about swaping mxp pins.

Cannot find NI related documentation as to the pin numbers being wrong though

Change-Id: I71d84431dc9bc7bf22aa29b6633e49723311b5f7

fixed formatting on changed files

Change-Id: I5b7c16cd798132b6b20c1d03f334a95b42d2ee11
2016-06-24 19:46:43 -07:00
Tyler Veness
aa22d4c33b Clarified that PID controller runs in discrete time (#107)
This was added to explain the apparent oversight with respect to controller behavior with different sample rates.
2016-06-20 23:25:23 -07:00
Thad House
046e043c4e Moves Interrupts over to Handles instead of pointers (#99) 2016-06-20 23:22:48 -07:00
Thad House
74fc10999b Fixes preferences formatting (#108) 2016-06-20 22:17:40 -07:00
Tyler Veness
cee9b2609d Added std:: prefix to more C standard library uses (#106) 2016-06-19 00:19:45 -07:00
Tyler Veness
daa0260a4e Deduplicated UsageReporting definitions (#104) 2016-06-19 00:15:57 -07:00
Tyler Veness
d66c61a36e Cleaned up robot startup and cleanup/shutdown code (#77)
Cleaned up RobotBase, removed singleton list from SensorBase, and removed unused typedefs and NULL_TASK macro from HAL's Task.hpp. Making the robot class instance static fixed non-POD statics used by the instance during destruction from being destroyed first.
2016-06-19 00:13:18 -07:00
Tyler Veness
ecc210f99a Rename Notifier::m_handlerMutex to Notifier::m_notifyMutex (#105)
A month ago, we discussed renaming this mutex to better reflect its current use, and this commit does that. The inline comment was also updated.
2016-06-18 02:20:29 -07:00
Thad House
3cacc2aba6 Switches indexed handles to shared_ptr (#101)
As discussed, the old method of was going to have issues, and was not
going to help in the case of the structs containing pointers. I think we
are just going to have to be careful, as guarenteeing the internal
pointers are const is going to be very difficult.
2016-06-18 00:59:53 -07:00
Peter Johnson
085c47b671 Unbreak wpilibc WritePreferencesToFile test. (#103)
ntcore recently changed GlobalDeleteAll() to not delete persistent values.
This test was relying on the old behavior to provide a clean slate.
2016-06-18 00:58:22 -07:00
Thad House
039515082a Fixes formatting in error.cpp (#102) 2016-06-17 21:35:00 -07:00
Thad House
c3908660b1 Switches all HAL Handle errors to be zero (#100)
As discussed, we don't really need the error checking specifically, as
we are just going to throw exceptions anyway, so this will make sure you
can check for 0 and be sure you catch any handle errors.
2016-06-17 20:21:25 -07:00
Thad House
fc515f4572 Changes HAL Port from a pointer to a handle (#93)
HAL Port is using a special handle, where the module and pin are bit
shifted straight into the handle. This is one of the few special cases
we have, but for the way port is used it is much cleaner and uses much
less memory.  Plus it is generic and not specific to one type.
2016-06-05 15:23:58 -07:00
Tyler Veness
5a82f73d9b Replaced .h C headers with c-prefixed version and added std:: prefix to C standard library usage (#90)
This was not done to stdint.h for brevity in type names. Also removed "using namespace std;".
2016-06-05 07:33:37 -07:00
Thad House
776a991d61 Moves Notifier over to handles (#97)
Internally, the linked list now uses shared_ptrs instead of raw
pointers. In addition, in the WPILib the notifier handle is now made
atomic. Then before the class is destructed, the handle is now set to 0.
This should help solve one of the existing race conditions. A 0 handle
is correctly handled down at the HAL level.
2016-06-05 07:29:47 -07:00
Thad House
8527f2c2a1 Fixes HandleResource classes (#95)
Issues were found when adding unit testing. The classes should now work
properly.
2016-06-03 11:24:58 -07:00
Thad House
c85b72b952 Fixes a few bugs in the initial handle implementation (#94)
Failure to check for invalid type on handle creation, and handle type
check was broken.
2016-06-01 20:12:50 -07:00
Peter Johnson
f0d9e19b5c ErrorBase: change to ostringstream. (#66)
This fixes a snprintf issue on 64-bit platforms by avoiding the use
of snprintf.
2016-06-01 00:12:55 -07:00
Tyler Veness
c7c011813f Made include ordering/organization more explicit in style guide (#86) 2016-05-31 23:46:44 -07:00
Thad House
d76f0d4022 Adds support for Handles to the HAL (#91)
Handles will be replacing opaque pointers in the HAL for better compatibility and easier error checking. This commits adds the initial resource manangement and definition for handles.
2016-05-31 23:45:47 -07:00
Peter Mitrano
de7678f2fc remove author requirement for now (#84)
waiting on a fix from pullapprove
2016-05-30 11:02:37 -04:00
Tyler Veness
2f7eff7091 Removed @author from comments (#88)
Keeping @author lines in the comments serves no functional purpose.
2016-05-29 09:24:04 -07:00
Tyler Veness
7a402b4170 Replaced "RoboRIO" with "roboRIO" in comments (#87) 2016-05-29 09:19:43 -07:00
Peter Johnson
10b4814e60 VisionAPI.cpp: Remove non-UTF8 characters. (#85) 2016-05-29 09:17:01 -07:00
Tyler Veness
613309c0a2 Replaced wpilibj class Init() methods with delegating constructors (#79) 2016-05-27 00:06:47 -07:00
Thad House
c622c03eff Places while loop around DS wait condition. (#83)
In case of Spontaneous wake ups, we should be checking a condition
variable as well.

Note that we can not use the existing m_newControlData, as that has a
possible race condition with existing user code that it does not look
like we could work around.
2016-05-26 23:05:08 -07:00
Thad House
ed7d2d6aa6 Splits the HAL Analog Implementation Files (#82) 2016-05-26 22:14:25 -07:00
Tyler Veness
51ff9e9f69 Classes which use I2C or SPI now do so via composition rather than inheritance (#72) 2016-05-26 21:37:23 -07:00
Tyler Veness
9f2f301fa4 Deduplicated FRC network communication headers (#71)
The network communication headers were moved to the include directory of the HAL and their copies were removed from wpilibc. Also, symModuleLink.h was removed because the function which it prototypes hasn't been used in WPILib since the roboRIO switch.
2016-05-26 20:20:58 -07:00
Tyler Veness
fa8bb3fa91 Remove obsolete timer functions and replace with std::chrono (#64)
Removed delayTicks(), delayMillis(), delaySeconds(), HAL_NO_WAIT, HAL_WAIT_FOREVER,
niTimestamp32(), and niTimestamp64().

Replaced clock_gettime() and usleep() with std::chrono.
2016-05-26 20:19:23 -07:00
Jonathan Leitschuh
4af0bbddee Add Travis Badge to ReadMe (#81)
This provides a quick navigation link to our travis build.
Additionally, it makes it so that the master build status can be confirmed quickly.
2016-05-26 15:54:12 -07:00
Tyler Veness
4aca3c2022 Removed extraneous curly braces around std::lock_guards in PIDController class (#78) 2016-05-26 12:59:34 -07:00
Tyler Veness
753ab85efb Removed commented out includes and imports (#76) 2016-05-26 12:59:01 -07:00
Thad House
da6b8c7ae1 Split HAL Digital Implementation files (#59)
Split to match the new headers. Uses a namespace 'hal' for internal functions and globals.
SPIAccumulator merged back into SPI header, as it was not a good split. Analog
accumulator will move back to analog input when the analog split is done.
2016-05-26 12:56:39 -07:00
Tyler Veness
305ab08f1c Renamed DriverStation::IsSysBrownedOut() to DriverStation::IsBrownedOut() to match the Java version. This changes the external API. (#67) 2016-05-25 23:09:24 -07:00
Tyler Veness
e9718fc7bf Replaced NULL with nullptr in C++ source files (#70) 2016-05-25 23:07:45 -07:00
Tyler Veness
8566878af4 Fixed C++ simulation build with Boost 1.60 (#49) 2016-05-25 22:41:58 -07:00
Tyler Veness
62812faf62 Clean up include guards and EOF newlines (#65)
* Replaced include guards with #pragma once

* All source files now have exactly one newline appended

Some files had either two newlines at the end or none (which isn't POSIX compliant). This patch fixes that.
2016-05-25 22:40:15 -07:00
Tyler Veness
d82635bbe1 Reordered headers according to the style guide (#58)
Subsections are alphabetized according to lexographic ordering. Also, HAL includes were moved from headers to source files where possible. This change may cause user code which uses HAL functionality and does not include the relevant HAL header (since it may have been provided by another WPILib header) to fail to compile.
2016-05-25 22:38:11 -07:00
Tyler Veness
a598e2d09b format.py: add missing 'sys' import (#69) 2016-05-25 21:11:43 -07:00
Tyler Veness
b5b2f0c7d8 Fixed typo in LinearDigitalFilter documentation (#62) 2016-05-25 20:27:34 -07:00
Tyler Veness
e6f6d24780 Removed empty default constructors and destructors from Gazebo plugins (#63) 2016-05-25 20:26:01 -07:00
Tyler Veness
21b2aabf18 Removed unused DS_LOG() macro (#61) 2016-05-25 20:25:06 -07:00
Tyler Veness
74f9da9da1 artf2612: Added Python script for updating license in source files (#57)
This is a follow-up of 3cd1253. A C++ program was written to automate the license update originally. That program was translated to Python so it can be kept in the repository and run when needed. It has been tested on Windows using the standard Python 3 installation and on Linux.

The original version skipped files that had "//" at the beginning since most were files that should be excluded. The relevant files are now in an exclusion list and the rest are processed normally. The .hpp file extension has been added as well. The script rewrote CompressorJNI.cpp to remove the carriage returns from its line endings.
2016-05-25 20:23:37 -07:00
Peter Johnson
e63830ed21 format.py: Fix running from styleguide directory on Windows. (#55) 2016-05-24 22:33:13 -07:00
Peter Johnson
eb51de65e5 format.py: Error out if no files found to format. (#56)
This can happen if the script is run from a directory other than the
project root or styleguide.
2016-05-24 22:16:53 -07:00
Peter Johnson
565a125dad Reformat for recent commits (#54) 2016-05-24 22:16:21 -07:00
Peter Johnson
3af8e7e9fd ControllerPower.cpp: Use quoted include instead of bracket for HAL. (#53)
This is consistent with all other source files.
2016-05-24 20:59:33 -07:00
Peter Mitrano
e3eae023da Cleanup of gazebo plugins (#46)
* Upgraded plugins for gazebo 7
* Fixed documentation on sensors
2016-05-24 20:27:24 -07:00
Thad House
6d9b3b0aaa Splits HAL Digital and Analog Headers into multiple headers (#52)
The Digital and Analog headers (and the implementations, but that will
be moved over later) are just too big and congested. This splits those
headers, and then changes the few things that needed to be changed in
WPILib to get the code working again. No function changes were made in
this commit.
2016-05-24 00:58:10 -07:00
Tyler Veness
9e99df1cf7 Removed sync group from SpeedController interface (#51)
CANJaguar is the only motor controller using sync groups, so that feature doesn't belong in an interface used by all motor controllers. If teams want to use sync groups, they should cast to the appropriate motor controller type themselves.
2016-05-23 20:42:58 -07:00
Thad House
e842ff7ad5 Explicitly stop the PIDController Notifier in the destructor (#48)
This helps reduce the probability of a PID Controller Segmentation Fault.
2016-05-22 23:24:10 -07:00
Peter Johnson
21b1e39b2a HAL Notifier: Use freelist to avoid use-after-free race. (#50)
As the notifierMutex is unlocked while the callback is being called in
alarmCallback(), it's possible for next to be invalidated due to a
cleanNotifier() call.  Now, instead of deleting the notifier immediately,
add it to a freelist to be cleaned up at the tail end of alarmCallback.
2016-05-22 23:21:45 -07:00
Thad House
8fc55c80a9 Renames all our .hpp HAL files to .h (#44)
Adds consistency, as the HAL was .hpp however all other code was .h.
2016-05-22 21:41:22 -07:00
Tyler Veness
248ca0c4a0 Added verbose flag to format.py (#47)
Making the "Processing" lines only print with a verbose option keeps the output clean.
2016-05-22 21:40:30 -07:00
Tyler Veness
0d655d7cec Ran formatter again (#45)
The previous wpilibc reformat missed an issue with CANTalon.h, and a patch merged since then didn't run the formatter.
2016-05-22 21:39:33 -07:00
Peter Mitrano
e71f454b9d Renamed folders for consistency, using sim/athena/shared schema (#27)
Rename the following folders:
hal/lib/Athena -> hal/lib/athena
hal/lib/Desktop -> hal/lib/sim
hal/lib/Shared -> hal/lib/shared
wpilibc/Athena -> wpilibc/athena
wpilibc/simulation -> wpilibc/sim

Windows users may need to run gradlew clean after updating.
2016-05-22 14:55:51 -07:00
Thad House
54092378e9 Changes HAL to return -1 to 1 for joysticks (#35)
First part of the HAL changes. Returns -1 to 1 for joysticks instead of
-128 to 127. Implemented by replacing the old structure with a new
structure that uses floats instead of shorts.
2016-05-21 01:42:16 -07:00
Thad House
a4f0c4fbe0 Implements locking in C++ DriverStation, and adds double buffering to DS Thread (#25)
Currently, about 5ms of every 20ms loop the DS thread would hold
the mutex, while grabbing data. During this time, and call to grab
joystick data would be blocked. This change grabs the joystick data
to a cache, and then grabs the mutex and moves the data references
around. This is much more efficient then the old code, and gives
teams more of their teleop loop time back for use.

Another major change this does is use preallocated arrays when entering
the JNI. Previously every JNI DS call would allocate an entire new array.
With a GC'd language where those arrays go on the heap, thats a problem,
and creates tons of garbage. That garbage is no longer created anymore,
as all arrays and byte buffers sent to JNI in the DS are preallocated.

In addition, GetJoystickName was always returning joystick 0 data, which
this fixes.
2016-05-21 00:41:15 -07:00
Omar Zrien
0965d60a71 Fixed a bug where using the two parameter constructor for CANTalon could cause invert-direction to not be initialized. (#26)
Original fix from Jacob Caporuscio
2016-05-20 23:08:35 -07:00
Peter Mitrano
f2d601d834 Use interrupt() in our interrupt exceptions (#24) 2016-05-20 23:06:07 -07:00
Tyler Veness
e14e45da76 Add format script which invokes clang-format on the C++ source code (#41)
On Windows machines, clang-format.exe must be in the PATH environment variable.
2016-05-20 17:30:37 -07:00
Peter Mitrano
68690643d2 Fix travis configuration to include compiling sim (#28) 2016-05-20 18:58:49 -04:00
Jonathan Leitschuh
00b2902102 Converts non hardware dependent tests to unit tests (#10) 2016-05-20 12:15:14 -07:00
Jonathan Leitschuh
975568c774 Adds Error Prone as compile time check to java projects (#13) 2016-05-20 10:48:41 -07:00
Jonathan Leitschuh
a834fff7b2 Applies Google Styleguide to Java parts of the library (#23)
This was partially applied to simulation but
simulation is a bit of a mess and has a lot of duplicated code.
2016-05-20 09:07:40 -07:00
Jonathan Leitschuh
64ab6e51fe Create .pullapprove.yml (#42) 2016-05-19 14:33:48 -04:00
PatrickPenguinTurtle
05a2089816 Fixed PCM tests by raising tolerance slightly (#15)
The PCM tests recently were failing by being slightly higher than voltage than expected. raised the tolerance to account for this.
Voltage was still clearly less than the on state while in the off state.

Change-Id: I8ac28867024f3ce7b4104fc03622e6133ac2b80f
2016-05-14 16:09:32 -04:00
Jonathan Leitschuh
b827f484be Add Slack Notification from Travis (#11) 2016-05-12 18:05:02 -04:00
Jonathan Leitschuh
000a98f193 Fix apt-get update -q causing build to fail (#20)
`sudo apt-get update -q` can fail a site doesn't respond.
This is the solution proposed here:
Related https://github.com/travis-ci/travis-ci/issues/5221
2016-05-12 17:51:57 -04:00
Fredric Silberberg
bb64dd3546 Updated README, and added in CONTRIBUTING. This adds tables of contents,
as well as fixing a few other issues.
2016-05-12 14:20:20 -04:00
Jonathan Leitschuh
d0c40b5ce2 Fixes indentation in .travis.yml 2016-05-11 15:06:06 -04:00
Jonathan Leitschuh
6794ff9ce8 Add Travis Build Configuration 2016-05-11 14:57:22 -04:00
Tyler Veness
083362bd86 Removed {@inheritDoc} from C++ sources and readded .inc files to Doxygen extension mapping
{@inheritDoc} doesn't exist in Doxygen, so I removed instances of it from the C++ source. It isn't needed anyway because Doxygen automatically fills in base class documentation for member functions in derived classes if no documentation is given. The extension mapping for .inc files was accidentally removed during the build system changes so this commit adds it back in.

Change-Id: I599e3bdafd76ee7d78a66090d81707cda5a399d7
2016-05-11 02:11:00 -07:00
Thad House
0f228e7b7d Implements a common PWMSpeedController base class
There was a lot of duplicated code between all 7 PWM speed controllers.
This moves all the duplicated code down to a base class, that will make
it easier to add speed controllers in future years if needed again. Also
if we need to add a method to all speed controllers, we only have to do
it in 1 place, and not 7.

Change-Id: I25eb1d097c0f5f7dbd7656db2f4a30d006d50f98
2016-05-11 01:01:31 -07:00
Tyler Veness
686f5d9fef Fix incorrect comments in the HAL I2C functions and incorrect return values for some I2C class member functions.
These issues were found and fixed while interfacing with an ITG3200 gyroscope. Fixes artf4173.

Change-Id: Id3c6b34aa707650480e90605e98ae1b44d7a7b98
2016-05-11 00:24:15 -07:00
Tyler Veness
ad8763fc8d Removed unused pcre.h header. If regexes are needed in the future, use C++11's regex header.
Change-Id: I0284943f3f09bbe9184885da6a486b82f73fd089
2016-05-10 23:12:36 -07:00
Thad House
1011b56b4c Fixes notifier restart error when last notifier is deleted
This actually isn't a large issue, since the HAL automatically creates a
notifier at the beginning to handle the time rollover, but during
testing without that, I noticed that deleting the last notifier would
disable notifiers for the entire lifetime of the program. This seemed to
be caused by the CLOSEST_TRIGGER static variable not being reset, and
causing new notifiers to never be added to the queue. This fixes that.
Not a bug that can be seen normally, but still a bug.

Change-Id: I6ac61c632918c90972cd0664aa833e3bc9e8c535
2016-05-10 23:06:13 -07:00
Peter Johnson
5904314a75 Improve ADXRS450 error detection.
Ensure the POR, PWR, and CST error bits are not set when reading the sample.

Reported by: Jared Russell, Austin Schuh

Change-Id: Ib38178d6b51880480aee86e13c16f9ba89a80693
2016-05-10 23:04:54 -07:00
Thad House
e852547344 Makes Java Timer timing more accurate
Java was using integer division for calulating Timer values, which
was causing Timer values to be concatinated, and only accurate
to the nearest millisecond. This changes it to use double division,
which matches C++ and makes timing much more accurate

Change-Id: I61b893f4ad5791bf4dfdd767ee4346c1ed4ea418
2016-05-10 23:02:35 -07:00
Peter Johnson
fa8b68419f Make Java AnalogGyro.getAngle() thread-safe.
In the Java implementation, "result" is an instance variable (to avoid
needing to perform a memory allocation on each call to getAngle).  However,
this means that calls to getAngle() from multiple threads can step on each
other.  Synchronize the method to avoid this issue.

Reported by: Jackson Gray (http://www.chiefdelphi.com/forums/showthread.php?threadid=145124)

Note this does not synchronize accesses between configuration methods such
as calibrate() and accessor methods such as getAngle().

Change-Id: I9ecc962d4fba66f6134fd801cfd607f155b41fe5
2016-05-09 20:36:36 -07:00
Fredric Silberberg
ec13d00b18 Fixed gradle build issue where files were not getting added to the wpilib java jar correctly.
Change-Id: I6c3cdd9906a94ff2d00340eb060a629d26c39a4a
2016-05-09 12:53:29 -07:00
Peter Johnson (294)
36447d86d8 Merge "Clear error buffer total when clearing the buffer contents" 2016-05-05 23:30:50 -07:00
Joe Ross
1e14403b3b Update POV documentation with examples of POV angles
Change-Id: If0f5b75366785b94a97b02694667fc00f8bfe196
2016-03-19 14:06:38 -07:00
Dustin Spicuzza
bee507eda8 Clear error buffer total when clearing the buffer contents
- Reported by Eli Barnett
- See http://www.chiefdelphi.com/forums/showthread.php?p=1559160`

Change-Id: I0efa4584452940bdfab3cc57c1823a8b33d387ff
2016-03-17 21:27:44 -04:00
1764 changed files with 150891 additions and 202561 deletions

107
.clang-format Normal file
View File

@@ -0,0 +1,107 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

50
.gitignore vendored
View File

@@ -1,13 +1,10 @@
# WPIlib Specific
dependency-reduced-pom.xml
/wpilibj/src/athena/cpp/nivision/*.c
/wpilibj/src/athena/cpp/nivision/*.cpp
/wpilibj/src/athena/cpp/nivision/*.s
/wpilibj/src/athena/cpp/nivision/*_arm.ini
/wpilibj/src/athena/cpp/nivision/*.java
/wpilibj/src/athena/cpp/nivision/nivision_funcs.txt
/wpilibj/src/athena/cpp/nivision/imaqdx_funcs.txt
/wpilibj/src/shared/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
/wpilibc/shared/src/WPILibVersion.cpp
/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
/wpilibc/src/main/native/cpp/WPILibVersion.cpp
doxygen.log
# Created by the jenkins test script
@@ -15,6 +12,8 @@ test-reports
# IntelliJ
*.iml
*.ipr
*.iws
.idea/
# Created by http://www.gitignore.io
@@ -155,6 +154,9 @@ local.properties
*.pyc
__pycache__
# Gradle wrapper
!gradle-wrapper.jar
# External tool builders
.externalToolBuilders/
@@ -181,3 +183,37 @@ NO
# Simulation folder stuff
!simulation/install_resources/*
# VSCode
.vscode/
#classpaths and projects
.project
.classpath
#Visual Studio
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
*.VC.db-shm
*.VC.db-wal
*.sln
*.vcxproj
*.vcxproj.filters
# Visual Studio 2015 cache/options directory
.vs/

View File

@@ -1,5 +0,0 @@
[gerrit]
host=usfirst.collab.net
port=29418
project=allwpilib
defaultbranch=master

41
.styleguide Normal file
View File

@@ -0,0 +1,41 @@
cppHeaderFileInclude {
\.h$
\.hpp$
\.inc$
}
cppSrcFileInclude {
\.cpp$
}
generatedFileExclude {
gmock/
ni-libraries/include/
ni-libraries/lib/
hal/src/main/native/athena/ctre/
hal/src/main/native/athena/frccansae/
hal/src/main/native/athena/visa/
hal/src/main/native/include/ctre/
UsageReporting\.h$
}
modifiableFileExclude {
wpilibj/src/arm-linux-jni/
wpilibj/src/main/native/cpp/
\.patch$
\.png$
\.py$
\.so$
}
includeOtherLibs {
^HAL/
^llvm/
^networktables/
^opencv2/
^support/
}
includeProject {
^ctre/
}

6
.styleguide-license Normal file
View File

@@ -0,0 +1,6 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) {year} FIRST. All Rights Reserved.{padding}*/
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/

40
.travis.yml Normal file
View File

@@ -0,0 +1,40 @@
sudo: true
dist: trusty
language: java
addons:
apt:
sources:
- deadsnakes
- ubuntu-toolchain-r-test
packages:
- g++-6
- python3.5
before_install:
- sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" > /etc/apt/sources.list.d/llvm.list'
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
- sudo apt-get update -q || true
- sudo apt-get install clang-format-5.0 -y
install:
- wget https://bootstrap.pypa.io/get-pip.py
- sudo python3.5 get-pip.py
- python3.5 -m pip install --user wpiformat
- mkdir -p $HOME/latest-gcc-symlinks # see travis-ci/travis-ci#3668
- ln -s /usr/bin/g++-6 $HOME/latest-gcc-symlinks/g++
- ln -s /usr/bin/gcc-6 $HOME/latest-gcc-symlinks/gcc
- export PATH=$HOME/latest-gcc-symlinks:$PATH
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
script:
- python3.5 -m wpiformat -y 2018 -clang 5.0
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
- ./gradlew --no-daemon --console=plain -PskipAthena :hal:halSimSharedLibrary :wpilibc:wpilibcSharedLibrary :wpilibj:wpilibJNISharedSharedLibrary :wpilibj:jar

View File

@@ -1,24 +0,0 @@
* Copyright (c) 2009-2016 FIRST
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,39 +0,0 @@
cmake_minimum_required(VERSION 2.8)
project(AllC++Sim)
include(CheckCXXCompilerFlag)
include (FindPkgConfig)
include(GNUInstallDirs)
#check for depenedencies
find_package(gazebo REQUIRED)
find_package(Boost COMPONENTS system filesystem REQUIRED)
#on windows we produce .dlls with no prefix
if(WIN32)
#allows us to define constexpr and noexcept in macros
#since msvc 2013 doesn't support them
add_definitions(-D_ALLOW_KEYWORD_MACROS)
# defines things like M_PI
add_definitions(-D_USE_MATH_DEFINES)
# get rid of min max macros on windows
add_definitions(-DNOMINMAX)
add_definitions(-DWIN32_LEAN_AND_MEAN)
SET(CMAKE_FIND_LIBRARY_PREFIXES "")
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
endif()
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFRC_SIMULATOR /MDd /Zi")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++1y -DFRC_SIMULATOR -Wno-unused-parameter -pthread -fPIC -fpermissive")
endif()
include_directories("build")
add_subdirectory(simulation/gz_msgs)
add_subdirectory(wpilibc/simulation)
add_subdirectory(simulation/frc_gazebo_plugins)

56
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,56 @@
# Contributing to WPILib
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules written here, and behave with Gracious Professionalism.
- [General Contribution Rules](#general-contribution-rules)
- [What to Contribute](#what-to-contribute)
- [Coding Guidelines](#coding-guidelines)
- [Submitting Changes](#submitting-changes)
- [Pull Request Format](#pull-request-format)
- [Merge Process](#merge-process)
- [Licensing](#licensing)
## General Contribution Rules
- Everything in the library must work for the 3000+ teams that will be using it.
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
- Tool suite changes must be generally useful to a broad range of teams
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
- Some features, such the addition of C++11 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only.
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Changes should have tests.
- Code should be well documented.
- This often involves ScreenSteps. To add content to ScreenSteps, we will work with you to get the appropriate articles written.
## What to Contribute
- Bug reports and fixes
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
- While we do welcome improvements to the API, there are a few important rules to consider:
- Features must be added to both WPILibC and WPILibJ, with rare exceptions.
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
- Features in WPILib should be broadly applicable to all teams. Anything that is team specific should not be submitted.
- As a rule, we are happy with the general structure of WPILib. We are not interested in major rewrites of all of WPILib. We are open to talking about ideas, but backwards compatibility is very important for WPILib, so be sure to keep this in mind when proposing major changes.
- Generally speaking, we do not accept code for specific sensors. We have to be able to test the sensor in hardware on the WPILib test bed. Additionally, hardware availability for teams is important. Therefore, as a general rule, the library only directly supports hardware that is in the Kit of Parts. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the master branch of WPILib. For most changes, we ask that you squash your changes down to a single commit. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. No change will be merged unless it is up to date with the current master. We will also not merge any changes with merge commits in them; please rebase off of master before submitting a pull request. We do this to make sure that the git history isn't too cluttered.
### Merge Process
When you first submit changes, Travis-CI will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Travis passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our Jenkins instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
## Licensing
By contributing to WPILib, you agree that your code will be distributed with WPILib, and licensed under the license for the WPILib project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as WPILib is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](license.txt).

24
LICENSE.txt Normal file
View File

@@ -0,0 +1,24 @@
Copyright (c) 2009-2017 FIRST
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the FIRST nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,36 +1,70 @@
# WPILib Project
[![Build Status](https://travis-ci.org/wpilibsuite/allwpilib.svg?branch=master)](https://travis-ci.org/wpilibsuite/allwpilib)
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
- [WPILib Mission](#wpilib-mission)
- [Building WPILib](#building-wpilib)
- [Requirements](#requirements)
- [Setup](#setup)
- [Building](#building)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
## WPILib Mission
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focussing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](license.txt).
# Building WPILib
Building WPILib is very straightforward. WPILib uses Gradle to compile. It only has a few dependencies on outside tools, including the ARM cross compiler.
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
## Requirements
- A C++ compiler
- On Linux, gcc works fine
- On Windows, you need Visual Studio 2015 (the free community edition works fine).
Make sure to select the C++ Programming Language for installation
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
* Note that for 2017-2018 and beyond, you will need version 5 or greater of gcc
- Doxygen (Only required if you want to build the C++ documentation)
## Setup
Clone the WPILib Repo. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
## Building
All build steps are executed using the Gradle wrapper, `gradlew`. Each target that Gradle can build is referred to as a task. The most common Gradle task to use is `build`. This will build all of the outputs created by WPILib. To run, open a console and cd into the cloned WPILib directory. Then:
All build steps are executed using the Gradle wrapper, `gradlew`. Each target that Gradle can build is referred to as a task. The most common Gradle task to use is `build`. This will build all the outputs created by WPILib. To run, open a console and cd into the cloned WPILib directory. Then:
```bash
./gradlew build
```
To build a specific subproject, such as wpilibc, you must access the subproject and run the build task only on that project. Accessing a subproject in Gradle is quite easy. Simply use `:subproject_name:task_name` with the Gradle wrapper. For example, building just wpilibc:
To build a specific subproject, such as WPILibC, you must access the subproject and run the build task only on that project. Accessing a subproject in Gradle is quite easy. Simply use `:subproject_name:task_name` with the Gradle wrapper. For example, building just WPILibC:
```bash
./gradlew :wpilibc:build
```
If you also want simulation to be build, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of gazebo should work, even on windows if you build from source. Correct means cmake needs to be able to find gazebo-config.cmake, which you get for free with ubuntu installs.
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
```bash
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
```
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
```bash
./gradlew build -PmakeSim
```
C++ simulation tasks (including plugins, gz_msgs, and wpilibcSim) all depend on gazebo_transport. In order for this to build you must have installed gazebo. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
If you prefer to use CMake directly, the you can still do so.
The common cmake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
The common CMake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
```bash
mkdir build #run this in the root of allwpilib
@@ -39,13 +73,15 @@ cmake ..
make
```
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change to the HAL and then run `:wpilibc:build`, the HAL will be rebuilt, then wpilibc.
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change in the HAL and then run `./gradlew :wpilibc:build`, the HAL will be rebuilt, then WPILibC.
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
## Publishing
If you are building to test with the eclipse plugins or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
If you are building to test with the Eclipse plugins or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
- development - The default repo.
- beta - Publishes to ~/releases/maven/beta.
@@ -54,20 +90,25 @@ If you are building to test with the eclipse plugins or just want to export the
The following maven targets a published by this task:
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - RoboRIO C++
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - roboRIO C++
- edu.wpi.first.wpilibc.simulation:WPILibCSim:0.1.0 - Simulation C++
- edu.wpi.first.wpilibj:wpilibJavaFinal:0.1.0-SNAPSHOT - RoboRIO Java
- edu.wpi.first.wpilibj:wpilibJavaFinal:0.1.0-SNAPSHOT - roboRIO Java
- edu.wpi.first.wpilibj:wpilibJavaSim:0.1.0-SNAPSHOT - Simulation Java
- edu.wpi.first.wpilibj.simulation:SimDS:0.1.0-SNAPSHOT - The driverstation for controlling simulation.
- org.gazebosim:JavaGazebo:0.1.0-SNAPSHOT - Gazebo protocol for Java.
## Structure and Organization
The main wpilib code you're probably looking for is in wpilibj and wpilibc. Those directories are split into shared, sim, and athena. Athena contains the wpilib code meant to run on your RoboRIO. Sim is wpilib code meant to run on your computer with gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer with Gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The Simulation directory contains extra simulation tools and libraries, such as gz_msgs and JavaGazebo. See sub-directories for more information.
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The hal directory contains more C++ code meant to run on the RoboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
The styleguide directory contains the styleguide for C++ and Java code. Anything submitted to the wpilib project needs to follow the code style guides outlined in there.
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).
# Contributing to WPILib
See [CONTRIBUTING.md](CONTRIBUTING.md).

View File

@@ -1,9 +0,0 @@
cmake_minimum_required(VERSION 2.8)
INCLUDE(CMakeForceCompiler)
set(ARM_PREFIX arm-frc-linux-gnueabi)
set(CMAKE_SYSTEM_NAME Linux)
CMAKE_FORCE_CXX_COMPILER(${ARM_PREFIX}-g++ GNU)
CMAKE_FORCE_C_COMPILER(${ARM_PREFIX}-gcc GNU)
set(CMAKE_CXX_FLAGS "-std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-psabi" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g" CACHE STRING "" FORCE) # still want debugging for release?

View File

@@ -1,34 +1,188 @@
def enableSimulation = hasProperty('enableSimulation')
if (!hasProperty('repo')) {
ext.repo = 'development'
}
def repoBaseUrl = "http://first.wpi.edu/FRC/roborio/maven/${repo}"
def publishUrl = "${System.getProperty('user.home')}/releases/maven/${repo}"
ext.simulationInstallDir = "$rootDir/build/install/simulation"
allprojects {
ext.enableSimulation = enableSimulation
ext.repo = repo
import edu.wpi.first.nativeutils.NativeUtils
import edu.wpi.first.nativeutils.tasks.JNIHeaders
buildscript {
repositories {
mavenCentral()
mavenLocal()
maven {
url publishUrl
}
maven {
url repoBaseUrl
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.5.1'
}
}
plugins {
id 'net.ltgt.errorprone' version '0.0.10'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '2.0'
id 'idea'
}
ext.licenseFile = file("$rootDir/LICENSE.txt")
ext.getJNIHeadersClass = {
return JNIHeaders
}
ext.getClassifier = { binary->
return NativeUtils.getClassifier(binary)
}
ext.getPlatformPath = { binary->
return NativeUtils.getPlatformPath(binary)
}
ext.createComponentZipTasks = { components, name, base, type, project, func ->
def configMap = [:]
components.each {
if (it in NativeLibrarySpec && it.name == name) {
it.binaries.each {
def target = getClassifier(it)
if (configMap.containsKey(target)) {
configMap.get(target).add(it)
} else {
configMap.put(target, [])
configMap.get(target).add(it)
}
}
}
}
def taskList = []
def outputsFolder = file("$project.buildDir/outputs")
def baseN = base + name
configMap.each { key, value ->
def task = project.tasks.create(baseN + "-${key}", type) {
description = 'Creates component archive for platform ' + key
destinationDir = outputsFolder
classifier = key
baseName = baseN + '-classifier'
duplicatesStrategy = 'exclude'
from(licenseFile) {
into '/'
}
func(it, value)
}
taskList.add(task)
project.build.dependsOn task
project.artifacts {
task
}
}
return taskList
}
ext.createAllCombined = { list, name, base, type, project ->
def outputsFolder = file("$project.buildDir/outputs")
def baseN = base + name
def task = project.tasks.create(baseN + '-all', type) {
description = 'Creates component archive for all classifiers'
destinationDir = outputsFolder
classifier = 'all'
baseName = baseN + '-classifier'
duplicatesStrategy = 'exclude'
list.each {
it.outputs.files.each {
from project.zipTree(it)
}
dependsOn it
}
}
project.build.dependsOn task
project.artifacts {
task
}
return task
}
ext.includeStandardZipFormat = { task, value ->
value.each { binary->
if (binary.buildable) {
if (binary instanceof SharedLibraryBinarySpec) {
task.dependsOn binary.buildTask
task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) {
into getPlatformPath(binary) + '/shared'
}
task.from (binary.sharedLibraryFile) {
into getPlatformPath(binary) + '/shared'
}
task.from (binary.sharedLibraryLinkFile) {
into getPlatformPath(binary) + '/shared'
}
} else if (binary instanceof StaticLibraryBinarySpec) {
task.dependsOn binary.buildTask
task.from (binary.staticLibraryFile) {
into getPlatformPath(binary) + '/static'
}
}
}
}
}
// Ensure that the WPILibVersioningPlugin is setup by setting the release type, if releaseType wasn't
// already specified on the command line
if (!hasProperty('releaseType')) {
WPILibVersion {
releaseType = 'dev'
}
}
def pubVersion
if (project.hasProperty("publishVersion")) {
pubVersion = project.publishVersion
} else {
pubVersion = WPILibVersion.version
}
def outputsFolder = file("$buildDir/outputs")
def versionFile = file("$outputsFolder/version.txt")
task outputVersions() {
description = 'Prints the versions of wpilib to a file for use by the downstream packaging project'
group = 'Build'
outputs.files(versionFile)
doFirst {
buildDir.mkdir()
outputsFolder.mkdir()
}
doLast {
versionFile.write pubVersion
}
}
task build() {}
build.dependsOn outputVersions
task clean(type: Delete) {
delete buildDir
}
subprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'checkstyle'
ext.armBuild = true
repositories {
mavenCentral()
}
checkstyle {
toolVersion = "8.1"
configFile = new File(rootDir, "styleguide/checkstyle.xml")
}
// Disables doclint in java 8.
if (JavaVersion.current().isJava8Compatible()) {
@@ -36,12 +190,13 @@ subprojects {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
ext.setupWpilibRepo = { publishing ->
publishing.repositories.maven {
url = "${System.getProperty('user.home')}/releases/maven/${repo}"
url = WPILibVersion.mavenLocalUrl
}
}
}
apply from: 'cppSettings.gradle'
task wrapper(type: Wrapper) {
gradleVersion = '4.1'
}

235
config.gradle Normal file
View File

@@ -0,0 +1,235 @@
import edu.wpi.first.nativeutils.*
import org.gradle.internal.os.OperatingSystem
def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/Zi', '/FS', '/Zc:inline', '/MT']
def windowsReleaseCompilerArgs = ['/O2']
def windowsLinkerArgs = [ '/DEBUG:FULL' ]
def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ]
def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread']
def linuxLinkerArgs = ['-rdynamic', '-pthread']
def linuxReleaseCompilerArgs = ['-Og']
def linuxDebugCompilerArgs = ['-O0']
def linux32BitArg = '-m32'
def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g',
'-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field',
'-Wno-unused-const-variable', '-pthread']
def macReleaseCompilerArgs = ['-O2']
def macDebugCompilerArgs = ['-O0']
def mac32BitArg = '-m32'
def buildAll = project.hasProperty('buildAll')
def windows64PlatformDetect = {
def arch = System.getProperty("os.arch")
def isWin = OperatingSystem.current().isWindows()
if (buildAll) {
return isWin
} else {
return isWin && arch == 'amd64'
}
}
def windows32PlatformDetect = {
def arch = System.getProperty("os.arch")
def isWin = OperatingSystem.current().isWindows()
if (buildAll) {
return isWin
} else {
return isWin && arch == 'x86'
}
}
def linux32IntelPlatformDetect = {
def arch = System.getProperty("os.arch")
def isLinux = OperatingSystem.current().isLinux()
def isIntel = (arch == 'amd64' || arch == 'i386')
if (buildAll) {
return isLinux && isIntel
} else {
return isLinux && arch == 'i386'
}
}
def linux64IntelPlatformDetect = {
def arch = System.getProperty("os.arch")
def isLinux = OperatingSystem.current().isLinux()
def isIntel = (arch == 'amd64' || arch == 'i386')
if (buildAll) {
return isLinux && isIntel
} else {
return isLinux && arch == 'amd64'
}
}
def linuxArmPlatformDetect = {
def arch = System.getProperty("os.arch")
def isIntel = (arch == 'amd64' || arch == 'i386')
return OperatingSystem.current().isLinux() && !isIntel
}
def mac64PlatformDetect = {
def arch = System.getProperty("os.arch")
def isMac = OperatingSystem.current().isMacOsX()
if (buildAll) {
return isMac
} else {
return isMac && arch == 'x86_64'
}
}
def mac32PlatformDetect = {
def arch = System.getProperty("os.arch")
def isMac = OperatingSystem.current().isMacOsX()
if (buildAll) {
return isMac
} else {
return isMac && arch == 'x86'
}
}
if (!project.hasProperty('skipAthena')) {
model {
buildConfigs {
roboRio(CrossBuildConfig) {
architecture = 'athena'
operatingSystem = 'linux'
toolChainPrefix = 'arm-frc-linux-gnueabi-'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
exclude << 'halSim'
exclude << 'halSimStaticDeps'
exclude << 'halSimTestingBase'
exclude << 'wpilibcTestingBase'
}
}
}
}
if (!project.hasProperty('onlyAthena')) {
model {
buildConfigs {
winX86(BuildConfig) {
architecture = 'x86'
operatingSystem = 'windows'
compilerArgs = windowsCompilerArgs
linkerArgs = windowsLinkerArgs
releaseCompilerArgs = windowsReleaseCompilerArgs
releaseLinkerArgs = windowsReleaseLinkerArgs
compilerFamily = 'VisualCpp'
detectPlatform = windows32PlatformDetect
exclude << 'halAthena'
}
winX64(BuildConfig) {
architecture = 'x86-64'
operatingSystem = 'windows'
compilerArgs = windowsCompilerArgs
linkerArgs = windowsLinkerArgs
releaseCompilerArgs = windowsReleaseCompilerArgs
releaseLinkerArgs = windowsReleaseLinkerArgs
compilerFamily = 'VisualCpp'
detectPlatform = windows64PlatformDetect
exclude << 'halAthena'
}
/* Disable 32 bit linux until we can figure out jenkins
linuxX86(BuildConfig) {
architecture = 'x86'
operatingSystem = 'linux'
compilerArgs = linuxCompilerArgs
compilerArgs << linux32BitArg
linkerArgs = linuxLinkerArgs
linkerArgs << linux32BitArg
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linux32IntelPlatformDetect
exclude << 'halAthena'
}
*/
linuxX64(BuildConfig) {
architecture = 'x86-64'
operatingSystem = 'linux'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linux64IntelPlatformDetect
exclude << 'halAthena'
}
/* 32 bit Mac OS X not supported by OpenCV.
* If support is ever added, will add this back in
macX86(BuildConfig) {
architecture = 'x86'
operatingSystem = 'osx'
compilerArgs = macCompilerArgs
compilerArgs << mac32BitArg
linkerArgs << mac32BitArg
debugCompilerArgs = macDebugCompilerArgs
releaseCompilerArgs = macReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Clang'
detectPlatform = mac32PlatformDetect
exclude << 'halAthena'
}
*/
macX64(BuildConfig) {
architecture = 'x86-64'
operatingSystem = 'osx'
compilerArgs = macCompilerArgs
debugCompilerArgs = macDebugCompilerArgs
releaseCompilerArgs = macReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Clang'
detectPlatform = mac64PlatformDetect
exclude << 'halAthena'
}
}
}
}
if (project.hasProperty('linuxCross')) {
model {
buildConfigs {
linuxArm(CrossBuildConfig) {
architecture = 'nativearm'
operatingSystem = 'linux'
toolChainPrefix = 'PLEASE_PROVIDE_A_COMPILER_NAME'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
skipByDefault = true
compilerFamily = 'Gcc'
exclude << 'gmock'
exclude << 'halAthena'
}
}
}
} else {
model {
buildConfigs {
linuxArm(BuildConfig) {
architecture = 'nativearm'
operatingSystem = 'linux'
compilerArgs = linuxCompilerArgs
linkerArgs = linuxLinkerArgs
debugCompilerArgs = linuxDebugCompilerArgs
releaseCompilerArgs = linuxReleaseCompilerArgs
releaseStripBinaries = true
compilerFamily = 'Gcc'
detectPlatform = linuxArmPlatformDetect
exclude << 'halAthena'
}
}
}
}

View File

@@ -1,46 +0,0 @@
:: This file is a helper for allC++Sim
::
:: Usage: cd /build && ../configure
::
:: WARNING -- this is only temporary, and only meant for debug, and only works on my computer
@set WS=C:\Users\peter\gz-ws
@set BOOST_PATH=%WS%\boost_1_56_0
@set BOOST_LIBRARY_DIR=%BOOST_PATH%\lib64-msvc-12.0
@set PROTOBUF_PATH=%WS%\protobuf-2.6.0-win64-vc12
@set OGRE_PATH=%WS%\ogre_src_v1-8-1-vc12-x64-release-debug\build\install\Debug
@set OGRE_INCLUDE_DIR=%OGRE_PATH%\include;%OGRE_PATH%\include\OGRE;%OGRE_PATH%\include\OGRE\RTShaderSystem;%OGRE_PATH%\include\OGRE\Terrain;%OGRE_PATH%\include\OGRE\Paging
@set OGRE_LIBRARY_DIR=%OGRE_PATH%\lib\Debug
set OGRE_LIB_SUFFIX=_d.lib
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreOverlay%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
@set FREEIMAGE_PATH=%WS%\FreeImage-vc12-x64-release-debug
@set FREEIMAGE_INCLUDE_DIR=%FREEIMAGE_PATH%\Source
@set TBB_PATH=%WS%\tbb43_20141023oss
@set TBB_INCLUDEDIR=%TBB_PATH%\include
@set DLFCN_WIN32_PATH=%WS%\dlfcn-win32-vc12-x64-release-debug\build\install\Debug
@set DLFCN_WIN32_INCLUDE_DIR=%DLFCN_WIN32_PATH%\include
@set TINY_XML_INCLUDE_DIR=%WS%\sdformat\src\win\tinyxml
@set GAZEBO_PATH=%WS%\gazebo\build\install\Debug\lib\cmake\gazebo
@set SDFORMAT_PATH=%WS%\sdformat\build\install\Debug\lib\cmake\sdformat
@set IGNITION-MATH_PATH=%WS%\ign-math\build\install\Debug\lib\cmake\ignition-math2
@set INCLUDE=%TINY_XML_INCLUDE_DIR%;%FREEIMAGE_INCLUDE_DIR%;%TBB_INCLUDEDIR%;%DLFCN_WIN32_INCLUDE_DIR%;%INCLUDE%
@set LIB=%LIB%
cmake -G "NMake Makefiles"^
-DCMAKE_INSTALL_PREFIX=build^
-DCMAKE_PREFIX_PATH="%GAZEBO_PATH%;%SDFORMAT_PATH%;%IGNITION-MATH_PATH%"^
-DOGRE_FOUND=1^
-DOGRE_INCLUDE_DIRS="%OGRE_INCLUDE_DIR%"^
-DOGRE_LIBRARIES="%OGRE_LIBS%"^
-DPROTOBUF_SRC_ROOT_FOLDER="%PROTOBUF_PATH%"^
-DBOOST_ROOT="%BOOST_PATH%"^
-DBOOST_LIBRARYDIR="%BOOST_LIBRARY_DIR%"^
..

View File

@@ -1,194 +0,0 @@
// This regex matches either a Windows or Unix style file separator, then the lib part of the library,
// then the name of the library itself, and finally the .so extension at the end. The name of the library
// is in the libName capture group, which is extracted and used for the linker flags
def libPattern = /.*((\\/|\\).*)+lib(?<libName>.+).so$/
def niLibraryArgs = []
def niLibraryPath = file('ni-libraries').path
// The NI Library tree includes all non-wpi libraries, which is everything that doesn't have libwpi in the name
def niLibraryTree = fileTree(niLibraryPath)
niLibraryTree.include '*.so'
niLibraryTree.exclude '*wpi*.so'
// This adds all linker flags to the list of ni library linker flags
niLibraryTree.each { lib ->
def nameMatcher = (lib.path =~ libPattern)
if (nameMatcher[0].size() > 1) {
def name = nameMatcher.group('libName')
niLibraryArgs << '-l' + name
}
}
def armNtDependency =
project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:3.0.0-SNAPSHOT:arm@zip")
def armConfig = project.configurations.detachedConfiguration(armNtDependency)
armConfig.setTransitive(false)
def armNetTables = armConfig.files[0].canonicalFile
def desktopNetTables
if (project.hasProperty('makeSim')){
def desktopNtDependency =
project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:3.0.0-SNAPSHOT:desktop@zip")
def desktopConfig = project.configurations.detachedConfiguration(desktopNtDependency)
desktopConfig.setTransitive(false)
desktopNetTables = desktopConfig.files[0].canonicalFile
}
def netTablesUnzipLocation = "$buildDir/networktables"
// Create a task that will unzip the networktables files into a temporary build directory
task unzipNetworkTables(type: Copy) {
description = 'Unzips the networktables maven dependency so that the include files and libraries can be used'
group = 'WPILib'
if (project.hasProperty('makeSim')){
from zipTree(desktopNetTables)
}
from zipTree(armNetTables)
into netTablesUnzipLocation
}
task clean(type: Delete) {
description = "Deletes the build directory"
group = "Build"
delete buildDir
}
subprojects {
plugins.withType(CppPlugin).whenPluginAdded {
// This defines a project property that projects depending on network tables can use to setup that dependency.
ext.defineNetworkTablesProperties = {
ext.netTables = netTablesUnzipLocation
ext.netTablesInclude = "$netTablesUnzipLocation/include"
ext.netLibArmLocation = "$netTablesUnzipLocation/Linux/arm"
if (project.hasProperty('makeSim')){
ext.netLibDesktopLocation = "$netTablesUnzipLocation/Linux/amd64"
}
ext.netSharedLib = "$netLibArmLocation/libntcore.so"
ext.netStaticLib = "$netLibArmLocation/libntcore.a"
task addNetworkTablesLibraryLinks() {
description = 'Adds the linker flags for the networktables libraries retreived from maven'
group = 'WPILib'
dependsOn project(':').unzipNetworkTables
doLast {
binaries.all {
tasks.withType(CppCompile) {
// desktop version doesn't use all the NI libraries
// so only do this for arm libraries
String architecture = targetPlatform.architecture
if (architecture.contains('arm')){
linker.args netStaticLib
}
}
}
}
}
}
model {
buildTypes {
debug
}
// Adds a custom toolchain for our compiler prefix and options
toolChains {
gcc(Gcc) {
target('arm') {
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
// If this ever changes, the prefix will need to be changed here
def compilerPrefix = 'arm-frc-linux-gnueabi-'
cppCompiler.executable = compilerPrefix + cppCompiler.executable
linker.executable = compilerPrefix + linker.executable
assembler.executable = compilerPrefix + assembler.executable
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
// arm, and doesn't understand this flag, so it is removed from both
cppCompiler.withArguments { args ->
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
//TODO: When the compiler allows us to actually call deprecated functions from within
// deprecated function, remove this line (this will cause calling deprecated functions
// to be treated as a warning rather than an error).
args << '-Wno-error=deprecated-declarations'
args.remove('-m32')
}
linker.withArguments { args ->
args << '-rdynamic'
args.remove('-m32')
}
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
}
}
// Workaround for OS X. Macs for some reason want to use Xcode's gcc
// (which just wraps Clang), so we have to explicitly make it so
// that trying to compile with Clang will call gcc instead
macGcc(Clang) {
target('arm') {
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
// If this ever changes, the prefix will need to be changed here
def compilerPrefix = 'arm-frc-linux-gnueabi-'
cppCompiler.executable = compilerPrefix + 'g++'
linker.executable = compilerPrefix + 'g++'
assembler.executable = compilerPrefix + 'gcc'
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
// arm, and doesn't understand this flag, so it is removed from both
cppCompiler.withArguments { args ->
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
//TODO: When the compiler allows us to actually call deprecated functions from within
// deprecated function, remove this line (this will cause calling deprecated functions
// to be treated as a warning rather than an error).
args << '-Wno-error=deprecated-declarations'
args.remove('-m32')
}
linker.withArguments { args ->
args << '-rdynamic'
args.remove('-m32')
}
staticLibArchiver.executable = compilerPrefix + 'ar'
}
}
}
// The only platform is arm linux
platforms {
arm {
architecture 'arm'
operatingSystem 'linux'
}
}
}
// This task adds the appropriate linker flags for the NI libraries
task addNiLibraryLinks() {
description = 'Adds the linker flags for the NI libraries in the ni-library folders'
group = 'WPILib'
doLast {
binaries.all {
tasks.withType(CppCompile) {
// desktop version doesn't use all the NI libraries
// so only do this for arm libraries
String architecture = targetPlatform.architecture
if (architecture.contains('arm')){
linker.args << '-L' + niLibraryPath
linker.args.addAll(niLibraryArgs)
}
}
}
model {
repositories {
libs(PrebuiltLibraries) { libs ->
// Loops through all .so files (except files matching *libwpi*.so) in ../ni-libraries
// and includes them for linking
niLibraryTree.each { niLib ->
libs.create(niLib) {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file(niLib.path)
}
}
}
}
}
}
}
}
}
}

178
gen/wpilibj_frcnetcomm.py Executable file
View File

@@ -0,0 +1,178 @@
#!/usr/bin/env python3
# This script generates the network communication interface for wpilibj.
#
# This script takes no arguments and should be invoked from either the gen
# directory or the root directory of the project.
from datetime import date
import os
import re
import subprocess
# Check that the current directory is part of a Git repository
def inGitRepo(directory):
ret = subprocess.run(["git", "rev-parse"], stderr = subprocess.DEVNULL)
return ret.returncode == 0
def main():
if not inGitRepo("."):
print("Error: not invoked within a Git repository", file = sys.stderr)
sys.exit(1)
# Handle running in either the root or gen directories
configPath = "."
if os.getcwd().rpartition(os.sep)[2] == "gen":
configPath = ".."
outputName = configPath + \
"/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/FRCNetComm.java"
# Set initial copyright year and get current year
year = "2016"
currentYear = str(date.today().year)
# Start writing output file
with open(outputName + ".tmp", "w") as temp:
# Write first line of comment
temp.write("/*")
for i in range(0, 76):
temp.write("-")
temp.write("*/\n")
# Write second line of comment
temp.write("/* Copyright (c) FIRST ")
if year != currentYear:
temp.write(year)
temp.write("-")
temp.write(currentYear)
temp.write(". All Rights Reserved.")
for i in range(0, 24):
temp.write(" ")
if year == currentYear:
for i in range(0, 5):
temp.write(" ")
temp.write("*/\n")
# Write rest of lines of comment
temp.write("""\
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*""")
for i in range(0, 76):
temp.write("-")
temp.write("*/\n")
# Write preamble
temp.write("""
package edu.wpi.first.wpilibj.hal;
import edu.wpi.first.wpilibj.hal.JNIWrapper;
/**
* JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
*/
@SuppressWarnings(\"MethodName\")
public class FRCNetComm extends JNIWrapper {
""")
# Read enums from C++ source files
firstEnum = True
for fileName in ["LoadOut.h", "UsageReporting.h"]:
with open(configPath + "/hal/include/FRC_NetworkCommunication/" + \
fileName, "r") as cppSource:
while True:
# Read until an enum is encountered
line = ""
pos = -1
while line.find("enum") == -1:
line = cppSource.readline()
if line == "":
break
if line == "":
break
# If "{" is on next line, read next line
if line.find("{") == -1:
line = cppSource.readline()
# Write enum to output file as interface
values = []
line = cppSource.readline()
while line.find("}") == -1:
if line == "\n":
values.append("")
else:
if line[0] != "#":
line = line.strip()
if line[len(line) - 1] == ",":
values.append(line[0:len(line) - 1])
else:
values.append(line)
line = cppSource.readline()
# Extract enum name
nameStart = 0
for i, c in enumerate(line):
if c != " " and c != "}":
nameStart = i
break
enumName = line[nameStart:len(line) - 2]
# Write comment for interface name
# Only add newline if not the first enum
if firstEnum == True:
firstEnum = False
else:
temp.write("\n")
temp.write(" /**\n"
" * ")
# Splits camelcase string into words
enumCamel = re.findall(r'[A-Z](?:[a-z]+|[A-Z]*(?=[A-Z]|$))',
enumName)
temp.write(enumCamel[0] + " ")
for i in range(1, len(enumCamel)):
temp.write(enumCamel[i][0].lower() + \
enumCamel[i][1:len(enumCamel[i])] + " ")
temp.write("from " + fileName + "\n"
" */\n"
" @SuppressWarnings(\"TypeName\")\n"
" public interface " + enumName + " {\n")
# Write enum values
count = 0
for value in values:
# Pass through empty lines
if value == "":
temp.write("\n")
continue
if value.find("=") == -1:
value = value + " = " + str(count)
count += 1
# Add scoping for values from a different enum
if enumName != "tModuleType" and \
value.find("kModuleType") != -1:
value = value.replace("kModuleType",
"tModuleType.kModuleType")
temp.write(" int " + value[0:len(value)] + ";\n")
# Write end of enum
temp.write(" }\n")
# Write closing brace for file
temp.write("}\n")
# Replace old output file
try:
os.remove(outputName)
except OSError:
pass
os.rename(outputName + ".tmp", outputName)
if __name__ == "__main__":
main()

86
gmock/CMakeLists.txt Normal file
View File

@@ -0,0 +1,86 @@
########################################################################
# CMake build script for Google Mock.
#
# To run the tests for Google Mock itself on Linux, use 'make test' or
# ctest. You can select which tests to run using 'ctest -R regex'.
# For more options, run 'ctest --help'.
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
# A directory to find Google Test sources.
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt")
set(gtest_dir gtest)
else()
set(gtest_dir ../gtest)
endif()
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL)
if (COMMAND pre_project_set_up_hermetic_build)
# Google Test also calls hermetic setup functions from add_subdirectory,
# although its changes will not affect things at the current scope.
pre_project_set_up_hermetic_build()
endif()
########################################################################
#
# Project-wide settings
# Name of the project.
#
# CMake files in this project can refer to the root source directory
# as ${gmock_SOURCE_DIR} and to the root binary directory as
# ${gmock_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
project(gmock CXX C)
cmake_minimum_required(VERSION 2.6.2)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
endif()
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-format-nonliteral")
endif()
# Instructs CMake to process Google Test's CMakeLists.txt and add its
# targets to the current scope. We are placing Google Test's binary
# directory in a subdirectory of our own as VC compilation may break
# if they are the same (the default).
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest")
# Although Google Test's CMakeLists.txt calls this function, the
# changes there don't affect the current scope. Therefore we have to
# call it again here.
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
# Adds Google Mock's and Google Test's header directories to the search path.
include_directories("${gmock_SOURCE_DIR}/include"
"${gmock_SOURCE_DIR}"
"${gtest_SOURCE_DIR}/include"
# This directory is needed to build directly from Google
# Test sources.
"${gtest_SOURCE_DIR}")
########################################################################
#
# Defines the gmock & gmock_main libraries. User tests should link
# with one of them.
# Google Mock libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that Google Mock can be compiled by
# a user aggressive about warnings.
cxx_library(gmock
"${cxx_strict}"
"${gtest_dir}/src/gtest-all.cc"
src/gmock-all.cc)
cxx_library(gmock_main
"${cxx_strict}"
"${gtest_dir}/src/gtest-all.cc"
src/gmock-all.cc
src/gmock_main.cc)

28
gmock/LICENSE Normal file
View File

@@ -0,0 +1,28 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

44
gmock/build.gradle Normal file
View File

@@ -0,0 +1,44 @@
import org.gradle.internal.os.OperatingSystem
if (!project.hasProperty('onlyAthena')) {
apply plugin: 'cpp'
apply plugin: 'visual-studio'
apply plugin: 'edu.wpi.first.NativeUtils'
ext.gmockProject = true
apply from: '../config.gradle'
ext.addGmockToLinker = { binary->
binary.lib project: ':gmock', library: 'gmock', linkage: 'static'
}
model {
components {
gmock(NativeLibrarySpec) {
sources {
cpp {
source {
srcDirs = ['src', 'gtest/src']
includes = ['*-all.cc']
}
exportedHeaders {
srcDirs = ['include', 'gtest/include', '.', 'gtest']
includes = ['**/*.h', '**/*.cc']
}
}
}
binaries.all {
if (toolChain in VisualCpp) {
cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1'
} else {
cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC'
}
}
binaries.withType(SharedLibraryBinarySpec) {
buildable = false
}
}
}
}
}

View File

@@ -0,0 +1,69 @@
########################################################################
# CMake build script for Google Test.
#
# To run the tests for Google Test itself on Linux, use 'make test' or
# ctest. You can select which tests to run using 'ctest -R regex'.
# For more options, run 'ctest --help'.
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
# When other libraries are using a shared version of runtime libraries,
# Google Test also has to use one.
option(
gtest_force_shared_crt
"Use shared (DLL) run-time lib even when Google Test is built as static lib."
OFF)
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
include(cmake/hermetic_build.cmake OPTIONAL)
if (COMMAND pre_project_set_up_hermetic_build)
pre_project_set_up_hermetic_build()
endif()
########################################################################
#
# Project-wide settings
# Name of the project.
#
# CMake files in this project can refer to the root source directory
# as ${gtest_SOURCE_DIR} and to the root binary directory as
# ${gtest_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
project(gtest CXX C)
cmake_minimum_required(VERSION 2.6.2)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
endif()
# Define helper functions and macros used by Google Test.
include(cmake/internal_utils.cmake)
config_compiler_and_linker() # Defined in internal_utils.cmake.
# Where Google Test's .h files can be found.
include_directories(
${gtest_SOURCE_DIR}/include
${gtest_SOURCE_DIR})
# Where Google Test's libraries can be found.
link_directories(${gtest_BINARY_DIR}/src)
########################################################################
#
# Defines the gtest & gtest_main libraries. User tests should link
# with one of them.
# Google Test libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that gtest can be compiled by a user
# aggressive about warnings.
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
target_link_libraries(gtest_main gtest)

28
gmock/gtest/LICENSE Normal file
View File

@@ -0,0 +1,28 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,206 @@
# Defines functions and macros useful for building Google Test and
# Google Mock.
#
# Note:
#
# - This file will be run twice when building Google Mock (once via
# Google Test's CMakeLists.txt, and once via Google Mock's).
# Therefore it shouldn't have any side effects other than defining
# the functions and macros.
#
# - The functions/macros defined in this file may depend on Google
# Test and Google Mock's option() definitions, and thus must be
# called *after* the options have been defined.
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
#
# This must be a macro(), as inside a function string() can only
# update variables in the function scope.
macro(fix_default_compiler_settings_)
if (MSVC)
# For MSVC, CMake sets certain flags to defaults we want to override.
# This replacement code is taken from sample in the CMake Wiki at
# http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
foreach (flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
# When Google Test is built as a shared library, it should also use
# shared runtime libraries. Otherwise, it may end up with multiple
# copies of runtime library data in different modules, resulting in
# hard-to-find crashes. When it is built as a static library, it is
# preferable to use CRT as static libraries, as we don't have to rely
# on CRT DLLs being available. CMake always defaults to using shared
# CRT libraries, so we override that default here.
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
endif()
# We prefer more strict warning checking for building Google Test.
# Replaces /W3 with /W4 in defaults.
string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
endforeach()
endif()
endmacro()
# Defines the compiler/linker flags used to build Google Test and
# Google Mock. You can tweak these definitions to suit your need. A
# variable's value is empty before it's explicitly assigned to.
macro(config_compiler_and_linker)
if (NOT gtest_disable_pthreads)
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
find_package(Threads)
endif()
fix_default_compiler_settings_()
if (MSVC)
# Newlines inside flags variables break CMake's NMake generator.
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi")
if (MSVC_VERSION LESS 1400)
# Suppress spurious warnings MSVC 7.1 sometimes issues.
# Forcing value to bool.
set(cxx_base_flags "${cxx_base_flags} -wd4800")
# Copy constructor and assignment operator could not be generated.
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
# Compatibility warnings not applicable to Google Test.
# Resolved overload was found by argument-dependent lookup.
set(cxx_base_flags "${cxx_base_flags} -wd4675")
endif()
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-GR-")
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow")
set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions")
# Until version 4.3.2, GCC doesn't define a macro to indicate
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and
# RTTI are enabled, so we define GTEST_HAS_* explicitly.
set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
CMAKE_CXX_COMPILER_ID STREQUAL "XL")
# CMake 2.8 changes Visual Age's compiler ID to "XL".
set(cxx_exception_flags "-qeh")
set(cxx_no_exception_flags "-qnoeh")
# Until version 9.0, Visual Age doesn't define a macro to indicate
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
set(cxx_base_flags "-AA -mt")
set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
# RTTI can not be disabled in HP aCC compiler.
set(cxx_no_rtti_flags "")
endif()
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed.
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
else()
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0")
endif()
# For building gtest's own tests and samples.
set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
set(cxx_no_exception
"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
set(cxx_default "${cxx_exception}")
set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
# For building the gtest libraries.
set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
endmacro()
# Defines the gtest & gtest_main libraries. User tests should link
# with one of them.
function(cxx_library_with_type name type cxx_flags)
# type can be either STATIC or SHARED to denote a static or shared library.
# ARGN refers to additional arguments after 'cxx_flags'.
add_library(${name} ${type} ${ARGN})
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
set_target_properties(${name}
PROPERTIES
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
endif()
if (CMAKE_USE_PTHREADS_INIT)
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
endif()
endfunction()
########################################################################
#
# Helper functions for creating build targets.
function(cxx_shared_library name cxx_flags)
cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
endfunction()
function(cxx_library name cxx_flags)
cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN})
endfunction()
# cxx_executable_with_flags(name cxx_flags libs srcs...)
#
# creates a named C++ executable that depends on the given libraries and
# is built from the given source files with the given compiler flags.
function(cxx_executable_with_flags name cxx_flags libs)
add_executable(${name} ${ARGN})
if (cxx_flags)
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
endif()
if (BUILD_SHARED_LIBS)
set_target_properties(${name}
PROPERTIES
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
endif()
# To support mixing linking in static and dynamic libraries, link each
# library in with an extra call to target_link_libraries.
foreach (lib "${libs}")
target_link_libraries(${name} ${lib})
endforeach()
endfunction()
# cxx_executable(name dir lib srcs...)
#
# creates a named target that depends on the given libs and is built
# from the given source files. dir/name.cc is implicitly included in
# the source file list.
function(cxx_executable name dir libs)
cxx_executable_with_flags(
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
endfunction()
# cxx_test_with_flags(name cxx_flags libs srcs...)
#
# creates a named C++ test that depends on the given libs and is built
# from the given source files with the given compiler flags.
function(cxx_test_with_flags name cxx_flags libs)
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
add_test(${name} ${name})
endfunction()
# cxx_test(name libs srcs...)
#
# creates a named test target that depends on the given libs and is
# built from the given source files. Unlike cxx_test_with_flags,
# test/name.cc is already implicitly included in the source file list.
function(cxx_test name libs)
cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
"test/${name}.cc" ${ARGN})
endfunction()

View File

@@ -1,294 +1,294 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this
// directly.
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h"
namespace testing {
// This flag controls the style of death tests. Valid values are "threadsafe",
// meaning that the death test child process will re-execute the test binary
// from the start, running only a single death test, or "fast",
// meaning that the child process will execute the test logic immediately
// after forking.
GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST
namespace internal {
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
GTEST_API_ bool InDeathTestChild();
} // namespace internal
// The following macros are useful for writing death tests.
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
// executed:
//
// 1. It generates a warning if there is more than one active
// thread. This is because it's safe to fork() or clone() only
// when there is a single thread.
//
// 2. The parent process clone()s a sub-process and runs the death
// test in it; the sub-process exits with code 0 at the end of the
// death test, if it hasn't exited already.
//
// 3. The parent process waits for the sub-process to terminate.
//
// 4. The parent process checks the exit code and error message of
// the sub-process.
//
// Examples:
//
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
// for (int i = 0; i < 5; i++) {
// EXPECT_DEATH(server.ProcessRequest(i),
// "Invalid request .* in ProcessRequest()")
// << "Failed to die on request " << i;
// }
//
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
//
// bool KilledBySIGHUP(int exit_code) {
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
// }
//
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
//
// On the regular expressions used in death tests:
//
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax.
//
// On other platforms (e.g. Windows), we only support a simple regex
// syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE
// or POSIX extended regex syntax. For example, we don't support
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
// repetition count ("x{5,7}"), among others.
//
// Below is the syntax that we do support. We chose it to be a
// subset of both PCRE and POSIX extended regex, so it's easy to
// learn wherever you come from. In the following: 'A' denotes a
// literal character, period (.), or a single \\ escape sequence;
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
// natural numbers.
//
// c matches any literal character c
// \\d matches any decimal digit
// \\D matches any character that's not a decimal digit
// \\f matches \f
// \\n matches \n
// \\r matches \r
// \\s matches any ASCII whitespace, including \n
// \\S matches any character that's not a whitespace
// \\t matches \t
// \\v matches \v
// \\w matches any letter, _, or decimal digit
// \\W matches any character that \\w doesn't match
// \\c matches any literal character c, which must be a punctuation
// . matches any single character except \n
// A? matches 0 or 1 occurrences of A
// A* matches 0 or many occurrences of A
// A+ matches 1 or many occurrences of A
// ^ matches the beginning of a string (not that of each line)
// $ matches the end of a string (not that of each line)
// xy matches x followed by y
//
// If you accidentally use PCRE or POSIX extended regex features
// not implemented by us, you will get a run-time failure. In that
// case, please try to rewrite your regular expression within the
// above syntax.
//
// This implementation is *not* meant to be as highly tuned or robust
// as a compiled regex library, but should perform well enough for a
// death test, which already incurs significant overhead by launching
// a child process.
//
// Known caveats:
//
// A "threadsafe" style death test obtains the path to the test
// program from argv[0] and re-executes it in the sub-process. For
// simplicity, the current implementation doesn't search the PATH
// when launching the sub-process. This means that the user must
// invoke the test program via a path that contains at least one
// path separator (e.g. path/to/foo_test and
// /absolute/path/to/bar_test are fine, but foo_test is not). This
// is rarely a problem as people usually don't put the test binary
// directory in PATH.
//
// TODO(wan@google.com): make thread-safe death tests search the PATH.
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
// that matches regex.
# define ASSERT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the
// test case, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
// Asserts that a given statement causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches regex.
# define ASSERT_DEATH(statement, regex) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Like ASSERT_DEATH, but continues on to successive tests in the
// test case, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code.
class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
bool operator()(int exit_status) const;
private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
const int exit_code_;
};
# if !GTEST_OS_WINDOWS
// Tests that an exit code describes an exit due to termination by a
// given signal.
class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
private:
const int signum_;
};
# endif // !GTEST_OS_WINDOWS
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
// The death testing framework causes this to have interesting semantics,
// since the sideeffects of the call are only visible in opt mode, and not
// in debug mode.
//
// In practice, this can be used to test functions that utilize the
// LOG(DFATAL) macro using the following style:
//
// int DieInDebugOr12(int* sideeffect) {
// if (sideeffect) {
// *sideeffect = 12;
// }
// LOG(DFATAL) << "death";
// return 12;
// }
//
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
// int sideeffect = 0;
// // Only asserts in dbg.
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
//
// #ifdef NDEBUG
// // opt-mode has sideeffect visible.
// EXPECT_EQ(12, sideeffect);
// #else
// // dbg-mode no visible sideeffect.
// EXPECT_EQ(0, sideeffect);
// #endif
// }
//
// This will assert that DieInDebugReturn12InOpt() crashes in debug
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
// appropriate fallback value (12 in this case) in opt mode. If you
// need to test that a function has appropriate side-effects in opt
// mode, include assertions against the side-effects. A general
// pattern for this is:
//
// EXPECT_DEBUG_DEATH({
// // Side-effects here will have an effect after this statement in
// // opt mode, but none in debug mode.
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
// }, "death");
//
# ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# else
# define EXPECT_DEBUG_DEATH(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
ASSERT_DEATH(statement, regex)
# endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is
// useful when you are combining death test assertions with normal test
// assertions in one test.
#if GTEST_HAS_DEATH_TEST
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex)
#else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
#endif
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this
// directly.
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h"
namespace testing {
// This flag controls the style of death tests. Valid values are "threadsafe",
// meaning that the death test child process will re-execute the test binary
// from the start, running only a single death test, or "fast",
// meaning that the child process will execute the test logic immediately
// after forking.
GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST
namespace internal {
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
GTEST_API_ bool InDeathTestChild();
} // namespace internal
// The following macros are useful for writing death tests.
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
// executed:
//
// 1. It generates a warning if there is more than one active
// thread. This is because it's safe to fork() or clone() only
// when there is a single thread.
//
// 2. The parent process clone()s a sub-process and runs the death
// test in it; the sub-process exits with code 0 at the end of the
// death test, if it hasn't exited already.
//
// 3. The parent process waits for the sub-process to terminate.
//
// 4. The parent process checks the exit code and error message of
// the sub-process.
//
// Examples:
//
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
// for (int i = 0; i < 5; i++) {
// EXPECT_DEATH(server.ProcessRequest(i),
// "Invalid request .* in ProcessRequest()")
// << "Failed to die on request " << i;
// }
//
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
//
// bool KilledBySIGHUP(int exit_code) {
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
// }
//
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
//
// On the regular expressions used in death tests:
//
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax.
//
// On other platforms (e.g. Windows), we only support a simple regex
// syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE
// or POSIX extended regex syntax. For example, we don't support
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
// repetition count ("x{5,7}"), among others.
//
// Below is the syntax that we do support. We chose it to be a
// subset of both PCRE and POSIX extended regex, so it's easy to
// learn wherever you come from. In the following: 'A' denotes a
// literal character, period (.), or a single \\ escape sequence;
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
// natural numbers.
//
// c matches any literal character c
// \\d matches any decimal digit
// \\D matches any character that's not a decimal digit
// \\f matches \f
// \\n matches \n
// \\r matches \r
// \\s matches any ASCII whitespace, including \n
// \\S matches any character that's not a whitespace
// \\t matches \t
// \\v matches \v
// \\w matches any letter, _, or decimal digit
// \\W matches any character that \\w doesn't match
// \\c matches any literal character c, which must be a punctuation
// . matches any single character except \n
// A? matches 0 or 1 occurrences of A
// A* matches 0 or many occurrences of A
// A+ matches 1 or many occurrences of A
// ^ matches the beginning of a string (not that of each line)
// $ matches the end of a string (not that of each line)
// xy matches x followed by y
//
// If you accidentally use PCRE or POSIX extended regex features
// not implemented by us, you will get a run-time failure. In that
// case, please try to rewrite your regular expression within the
// above syntax.
//
// This implementation is *not* meant to be as highly tuned or robust
// as a compiled regex library, but should perform well enough for a
// death test, which already incurs significant overhead by launching
// a child process.
//
// Known caveats:
//
// A "threadsafe" style death test obtains the path to the test
// program from argv[0] and re-executes it in the sub-process. For
// simplicity, the current implementation doesn't search the PATH
// when launching the sub-process. This means that the user must
// invoke the test program via a path that contains at least one
// path separator (e.g. path/to/foo_test and
// /absolute/path/to/bar_test are fine, but foo_test is not). This
// is rarely a problem as people usually don't put the test binary
// directory in PATH.
//
// TODO(wan@google.com): make thread-safe death tests search the PATH.
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
// that matches regex.
# define ASSERT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the
// test case, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
// Asserts that a given statement causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches regex.
# define ASSERT_DEATH(statement, regex) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Like ASSERT_DEATH, but continues on to successive tests in the
// test case, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code.
class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
bool operator()(int exit_status) const;
private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
const int exit_code_;
};
# if !GTEST_OS_WINDOWS
// Tests that an exit code describes an exit due to termination by a
// given signal.
class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
private:
const int signum_;
};
# endif // !GTEST_OS_WINDOWS
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
// The death testing framework causes this to have interesting semantics,
// since the sideeffects of the call are only visible in opt mode, and not
// in debug mode.
//
// In practice, this can be used to test functions that utilize the
// LOG(DFATAL) macro using the following style:
//
// int DieInDebugOr12(int* sideeffect) {
// if (sideeffect) {
// *sideeffect = 12;
// }
// LOG(DFATAL) << "death";
// return 12;
// }
//
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
// int sideeffect = 0;
// // Only asserts in dbg.
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
//
// #ifdef NDEBUG
// // opt-mode has sideeffect visible.
// EXPECT_EQ(12, sideeffect);
// #else
// // dbg-mode no visible sideeffect.
// EXPECT_EQ(0, sideeffect);
// #endif
// }
//
// This will assert that DieInDebugReturn12InOpt() crashes in debug
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
// appropriate fallback value (12 in this case) in opt mode. If you
// need to test that a function has appropriate side-effects in opt
// mode, include assertions against the side-effects. A general
// pattern for this is:
//
// EXPECT_DEBUG_DEATH({
// // Side-effects here will have an effect after this statement in
// // opt mode, but none in debug mode.
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
// }, "death");
//
# ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# else
# define EXPECT_DEBUG_DEATH(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
ASSERT_DEATH(statement, regex)
# endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is
// useful when you are combining death test assertions with normal test
// assertions in one test.
#if GTEST_HAS_DEATH_TEST
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex)
#else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
#endif
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_

View File

@@ -1,250 +1,250 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the Message class.
//
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
// leave some internal implementation details in this header file.
// They are clearly marked by comments like this:
//
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
//
// Such code is NOT meant to be used by a user directly, and is subject
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program!
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
#include "gtest/internal/gtest-port.h"
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int);
namespace testing {
// The Message class works like an ostream repeater.
//
// Typical usage:
//
// 1. You stream a bunch of values to a Message object.
// It will remember the text in a stringstream.
// 2. Then you stream the Message object to an ostream.
// This causes the text in the Message to be streamed
// to the ostream.
//
// For example;
//
// testing::Message foo;
// foo << 1 << " != " << 2;
// std::cout << foo;
//
// will print "1 != 2".
//
// Message is not intended to be inherited from. In particular, its
// destructor is not virtual.
//
// Note that stringstream behaves differently in gcc and in MSVC. You
// can stream a NULL char pointer to it in the former, but not in the
// latter (it causes an access violation if you do). The Message
// class hides this difference by treating a NULL char pointer as
// "(null)".
class GTEST_API_ Message {
private:
// The type of basic IO manipulators (endl, ends, and flush) for
// narrow streams.
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
public:
// Constructs an empty Message.
Message();
// Copy constructor.
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
*ss_ << msg.GetString();
}
// Constructs a Message from a C-string.
explicit Message(const char* str) : ss_(new ::std::stringstream) {
*ss_ << str;
}
#if GTEST_OS_SYMBIAN
// Streams a value (either a pointer or not) to this object.
template <typename T>
inline Message& operator <<(const T& value) {
StreamHelper(typename internal::is_pointer<T>::type(), value);
return *this;
}
#else
// Streams a non-pointer value to this object.
template <typename T>
inline Message& operator <<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test
// assertions, testing::Message must access the custom << operator
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using ::operator <<;
*ss_ << val;
return *this;
}
// Streams a pointer value to this object.
//
// This function is an overload of the previous one. When you
// stream a pointer to a Message, this definition will be used as it
// is more specialized. (The C++ Standard, section
// [temp.func.order].) If you stream a non-pointer, then the
// previous definition will be used.
//
// The reason for this overload is that streaming a NULL pointer to
// ostream is undefined behavior. Depending on the compiler, you
// may get "0", "(nil)", "(null)", or an access violation. To
// ensure consistent result across compilers, we always treat NULL
// as "(null)".
template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
return *this;
}
#endif // GTEST_OS_SYMBIAN
// Since the basic IO manipulators are overloaded for both narrow
// and wide streams, we have to provide this specialized definition
// of operator <<, even though its body is the same as the
// templatized version above. Without this definition, streaming
// endl or other basic IO manipulators to Message will confuse the
// compiler.
Message& operator <<(BasicNarrowIoManip val) {
*ss_ << val;
return *this;
}
// Instead of 1/0, we want to see true/false for bool values.
Message& operator <<(bool b) {
return *this << (b ? "true" : "false");
}
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str);
Message& operator <<(wchar_t* wide_c_str);
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::wstring& wstr);
#endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
std::string GetString() const;
private:
#if GTEST_OS_SYMBIAN
// These are needed as the Nokia Symbian Compiler cannot decide between
// const T& and const T* in a function template. The Nokia compiler _can_
// decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T>
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
}
template <typename T>
inline void StreamHelper(internal::false_type /*is_pointer*/,
const T& value) {
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using ::operator <<;
*ss_ << value;
}
#endif // GTEST_OS_SYMBIAN
// We'll hold the text streamed to this object here.
const internal::scoped_ptr< ::std::stringstream> ss_;
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.
void operator=(const Message&);
};
// Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return os << sb.GetString();
}
namespace internal {
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
template <typename T>
std::string StreamableToString(const T& streamable) {
return (Message() << streamable).GetString();
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the Message class.
//
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
// leave some internal implementation details in this header file.
// They are clearly marked by comments like this:
//
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
//
// Such code is NOT meant to be used by a user directly, and is subject
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program!
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
#include "gtest/internal/gtest-port.h"
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int);
namespace testing {
// The Message class works like an ostream repeater.
//
// Typical usage:
//
// 1. You stream a bunch of values to a Message object.
// It will remember the text in a stringstream.
// 2. Then you stream the Message object to an ostream.
// This causes the text in the Message to be streamed
// to the ostream.
//
// For example;
//
// testing::Message foo;
// foo << 1 << " != " << 2;
// std::cout << foo;
//
// will print "1 != 2".
//
// Message is not intended to be inherited from. In particular, its
// destructor is not virtual.
//
// Note that stringstream behaves differently in gcc and in MSVC. You
// can stream a NULL char pointer to it in the former, but not in the
// latter (it causes an access violation if you do). The Message
// class hides this difference by treating a NULL char pointer as
// "(null)".
class GTEST_API_ Message {
private:
// The type of basic IO manipulators (endl, ends, and flush) for
// narrow streams.
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
public:
// Constructs an empty Message.
Message();
// Copy constructor.
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
*ss_ << msg.GetString();
}
// Constructs a Message from a C-string.
explicit Message(const char* str) : ss_(new ::std::stringstream) {
*ss_ << str;
}
#if GTEST_OS_SYMBIAN
// Streams a value (either a pointer or not) to this object.
template <typename T>
inline Message& operator <<(const T& value) {
StreamHelper(typename internal::is_pointer<T>::type(), value);
return *this;
}
#else
// Streams a non-pointer value to this object.
template <typename T>
inline Message& operator <<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test
// assertions, testing::Message must access the custom << operator
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using ::operator <<;
*ss_ << val;
return *this;
}
// Streams a pointer value to this object.
//
// This function is an overload of the previous one. When you
// stream a pointer to a Message, this definition will be used as it
// is more specialized. (The C++ Standard, section
// [temp.func.order].) If you stream a non-pointer, then the
// previous definition will be used.
//
// The reason for this overload is that streaming a NULL pointer to
// ostream is undefined behavior. Depending on the compiler, you
// may get "0", "(nil)", "(null)", or an access violation. To
// ensure consistent result across compilers, we always treat NULL
// as "(null)".
template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
return *this;
}
#endif // GTEST_OS_SYMBIAN
// Since the basic IO manipulators are overloaded for both narrow
// and wide streams, we have to provide this specialized definition
// of operator <<, even though its body is the same as the
// templatized version above. Without this definition, streaming
// endl or other basic IO manipulators to Message will confuse the
// compiler.
Message& operator <<(BasicNarrowIoManip val) {
*ss_ << val;
return *this;
}
// Instead of 1/0, we want to see true/false for bool values.
Message& operator <<(bool b) {
return *this << (b ? "true" : "false");
}
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str);
Message& operator <<(wchar_t* wide_c_str);
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::wstring& wstr);
#endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
std::string GetString() const;
private:
#if GTEST_OS_SYMBIAN
// These are needed as the Nokia Symbian Compiler cannot decide between
// const T& and const T* in a function template. The Nokia compiler _can_
// decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T>
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
}
template <typename T>
inline void StreamHelper(internal::false_type /*is_pointer*/,
const T& value) {
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using ::operator <<;
*ss_ << value;
}
#endif // GTEST_OS_SYMBIAN
// We'll hold the text streamed to this object here.
const internal::scoped_ptr< ::std::stringstream> ss_;
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.
void operator=(const Message&);
};
// Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return os << sb.GetString();
}
namespace internal {
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
template <typename T>
std::string StreamableToString(const T& streamable) {
return (Message() << streamable).GetString();
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_

View File

@@ -1,487 +1,487 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It is usually derived from testing::TestWithParam<T> (see below for
// another inheritance scheme that's sometimes useful in more complicated
// class hierarchies), where the type of your parameter values.
// TestWithParam<T> is itself derived from testing::Test. T can be any
// copyable type. If it's a raw pointer, you are responsible for managing the
// lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions (including parameters to the
// generators) are evaluated in InitGoogleTest(), after main() has started.
// This allows the user on one hand, to adjust generator parameters in order
// to dynamically determine a set of tests to run and on the other hand,
// give the user a chance to inspect the generated tests with Google Test
// reflection API before RUN_ALL_TESTS() is executed.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
//
//
// A parameterized test fixture must be derived from testing::Test and from
// testing::WithParamInterface<T>, where T is the type of the parameter
// values. Inheriting from TestWithParam<T> satisfies that requirement because
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
// complicated hierarchies, however, it is occasionally useful to inherit
// separately from Test and WithParamInterface. For example:
class BaseTest : public ::testing::Test {
// You can inherit all the usual members for a non-parameterized test
// fixture here.
};
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
// The usual test fixture members go here too.
};
TEST_F(BaseTest, HasFoo) {
// This is an ordinary non-parameterized test.
}
TEST_P(DerivedTest, DoesBlah) {
// GetParam works just the same here as if you inherit from TestWithParam.
EXPECT_TRUE(foo.Blah(GetParam()));
}
#endif // 0
#include "gtest/internal/gtest-port.h"
#if !GTEST_OS_SYMBIAN
# include <utility>
#endif
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util-generated.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end) {
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
::value_type ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to $n parameters.
//
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
}
]]
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
# if GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to $maxtuple arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[typename Generator$j]]>
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
$for j, [[const Generator$j& g$j]]) {
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
$for j, [[g$j]]);
}
]]
# endif // GTEST_HAS_COMBINE
# define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It is usually derived from testing::TestWithParam<T> (see below for
// another inheritance scheme that's sometimes useful in more complicated
// class hierarchies), where the type of your parameter values.
// TestWithParam<T> is itself derived from testing::Test. T can be any
// copyable type. If it's a raw pointer, you are responsible for managing the
// lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions (including parameters to the
// generators) are evaluated in InitGoogleTest(), after main() has started.
// This allows the user on one hand, to adjust generator parameters in order
// to dynamically determine a set of tests to run and on the other hand,
// give the user a chance to inspect the generated tests with Google Test
// reflection API before RUN_ALL_TESTS() is executed.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
//
//
// A parameterized test fixture must be derived from testing::Test and from
// testing::WithParamInterface<T>, where T is the type of the parameter
// values. Inheriting from TestWithParam<T> satisfies that requirement because
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
// complicated hierarchies, however, it is occasionally useful to inherit
// separately from Test and WithParamInterface. For example:
class BaseTest : public ::testing::Test {
// You can inherit all the usual members for a non-parameterized test
// fixture here.
};
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
// The usual test fixture members go here too.
};
TEST_F(BaseTest, HasFoo) {
// This is an ordinary non-parameterized test.
}
TEST_P(DerivedTest, DoesBlah) {
// GetParam works just the same here as if you inherit from TestWithParam.
EXPECT_TRUE(foo.Blah(GetParam()));
}
#endif // 0
#include "gtest/internal/gtest-port.h"
#if !GTEST_OS_SYMBIAN
# include <utility>
#endif
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util-generated.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end) {
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
::value_type ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to $n parameters.
//
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
}
]]
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
# if GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to $maxtuple arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[typename Generator$j]]>
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
$for j, [[const Generator$j& g$j]]) {
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
$for j, [[g$j]]);
}
]]
# endif // GTEST_HAS_COMBINE
# define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_

View File

@@ -1,232 +1,232 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test).
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#include "gtest/gtest.h"
namespace testing {
// This helper class can be used to mock out Google Test failure reporting
// so that we can test Google Test or code that builds on Google Test.
//
// An object of this class appends a TestPartResult object to the
// TestPartResultArray object given in the constructor whenever a Google Test
// failure is reported. It can either intercept only failures that are
// generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor.
class GTEST_API_ ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface {
public:
// The two possible mocking modes of this object.
enum InterceptMode {
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
INTERCEPT_ALL_THREADS // Intercepts all failures.
};
// The c'tor sets this object as the test part result reporter used
// by Google Test. The 'result' parameter specifies where to report the
// results. This reporter will only catch failures generated in the current
// thread. DEPRECATED
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
// Same as above, but you can choose the interception scope of this object.
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
TestPartResultArray* result);
// The d'tor restores the previous test part result reporter.
virtual ~ScopedFakeTestPartResultReporter();
// Appends the TestPartResult object to the TestPartResultArray
// received in the constructor.
//
// This method is from the TestPartResultReporterInterface
// interface.
virtual void ReportTestPartResult(const TestPartResult& result);
private:
void Init();
const InterceptMode intercept_mode_;
TestPartResultReporterInterface* old_reporter_;
TestPartResultArray* const result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
};
namespace internal {
// A helper class for implementing EXPECT_FATAL_FAILURE() and
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
// TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated.
class GTEST_API_ SingleFailureChecker {
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type,
const string& substr);
~SingleFailureChecker();
private:
const TestPartResultArray* const results_;
const TestPartResult::Type type_;
const string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
};
} // namespace internal
} // namespace testing
// A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - 'statement' cannot reference local non-static variables or
// non-static members of the current object.
// - 'statement' cannot return a value.
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
// gtest_unittest.cc will fail to compile if we do that.
#define EXPECT_FATAL_FAILURE(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ALL_THREADS, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
// A macro for testing Google Test assertions or code that's expected to
// generate Google Test non-fatal failures. It asserts that the given
// statement will cause exactly one non-fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// 'statement' is allowed to reference local variables and members of
// the current object.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. If we do that, the code won't compile when the user gives
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
// expands to code containing an unprotected comma. The
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
// catches that.
//
// For the same reason, we have to write
// if (::testing::internal::AlwaysTrue()) { statement; }
// instead of
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
// to avoid an MSVC warning on unreachable code.
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test).
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#include "gtest/gtest.h"
namespace testing {
// This helper class can be used to mock out Google Test failure reporting
// so that we can test Google Test or code that builds on Google Test.
//
// An object of this class appends a TestPartResult object to the
// TestPartResultArray object given in the constructor whenever a Google Test
// failure is reported. It can either intercept only failures that are
// generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor.
class GTEST_API_ ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface {
public:
// The two possible mocking modes of this object.
enum InterceptMode {
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
INTERCEPT_ALL_THREADS // Intercepts all failures.
};
// The c'tor sets this object as the test part result reporter used
// by Google Test. The 'result' parameter specifies where to report the
// results. This reporter will only catch failures generated in the current
// thread. DEPRECATED
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
// Same as above, but you can choose the interception scope of this object.
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
TestPartResultArray* result);
// The d'tor restores the previous test part result reporter.
virtual ~ScopedFakeTestPartResultReporter();
// Appends the TestPartResult object to the TestPartResultArray
// received in the constructor.
//
// This method is from the TestPartResultReporterInterface
// interface.
virtual void ReportTestPartResult(const TestPartResult& result);
private:
void Init();
const InterceptMode intercept_mode_;
TestPartResultReporterInterface* old_reporter_;
TestPartResultArray* const result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
};
namespace internal {
// A helper class for implementing EXPECT_FATAL_FAILURE() and
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
// TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated.
class GTEST_API_ SingleFailureChecker {
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type,
const string& substr);
~SingleFailureChecker();
private:
const TestPartResultArray* const results_;
const TestPartResult::Type type_;
const string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
};
} // namespace internal
} // namespace testing
// A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - 'statement' cannot reference local non-static variables or
// non-static members of the current object.
// - 'statement' cannot return a value.
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
// gtest_unittest.cc will fail to compile if we do that.
#define EXPECT_FATAL_FAILURE(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ALL_THREADS, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
// A macro for testing Google Test assertions or code that's expected to
// generate Google Test non-fatal failures. It asserts that the given
// statement will cause exactly one non-fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// 'statement' is allowed to reference local variables and members of
// the current object.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. If we do that, the code won't compile when the user gives
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
// expands to code containing an unprotected comma. The
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
// catches that.
//
// For the same reason, we have to write
// if (::testing::internal::AlwaysTrue()) { statement; }
// instead of
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
// to avoid an MSVC warning on unreachable code.
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_

View File

@@ -1,179 +1,179 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
namespace testing {
// A copyable object representing the result of a test part (i.e. an
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
//
// Don't inherit from TestPartResult as its destructor is not virtual.
class GTEST_API_ TestPartResult {
public:
// The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
enum Type {
kSuccess, // Succeeded.
kNonFatalFailure, // Failed but the test can continue.
kFatalFailure // Failed and the test should be terminated.
};
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
TestPartResult(Type a_type,
const char* a_file_name,
int a_line_number,
const char* a_message)
: type_(a_type),
file_name_(a_file_name == NULL ? "" : a_file_name),
line_number_(a_line_number),
summary_(ExtractSummary(a_message)),
message_(a_message) {
}
// Gets the outcome of the test part.
Type type() const { return type_; }
// Gets the name of the source file where the test part took place, or
// NULL if it's unknown.
const char* file_name() const {
return file_name_.empty() ? NULL : file_name_.c_str();
}
// Gets the line in the source file where the test part took place,
// or -1 if it's unknown.
int line_number() const { return line_number_; }
// Gets the summary of the failure message.
const char* summary() const { return summary_.c_str(); }
// Gets the message associated with the test part.
const char* message() const { return message_.c_str(); }
// Returns true iff the test part passed.
bool passed() const { return type_ == kSuccess; }
// Returns true iff the test part failed.
bool failed() const { return type_ != kSuccess; }
// Returns true iff the test part non-fatally failed.
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
// Returns true iff the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; }
private:
Type type_;
// Gets the summary of the failure message by omitting the stack
// trace in it.
static std::string ExtractSummary(const char* message);
// The name of the source file where the test part took place, or
// "" if the source file is unknown.
std::string file_name_;
// The line in the source file where the test part took place, or -1
// if the line number is unknown.
int line_number_;
std::string summary_; // The test failure summary.
std::string message_; // The test failure message.
};
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// An array of TestPartResult objects.
//
// Don't inherit from TestPartResultArray as its destructor is not
// virtual.
class GTEST_API_ TestPartResultArray {
public:
TestPartResultArray() {}
// Appends the given TestPartResult to the array.
void Append(const TestPartResult& result);
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& GetTestPartResult(int index) const;
// Returns the number of TestPartResult objects in the array.
int size() const;
private:
std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
};
// This interface knows how to report a test part result.
class TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() {}
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
};
namespace internal {
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
// statement generates new fatal failures. To do so it registers itself as the
// current test part result reporter. Besides checking if fatal failures were
// reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
class GTEST_API_ HasNewFatalFailureHelper
: public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
virtual ~HasNewFatalFailureHelper();
virtual void ReportTestPartResult(const TestPartResult& result);
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private:
bool has_new_fatal_failure_;
TestPartResultReporterInterface* original_reporter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
};
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
namespace testing {
// A copyable object representing the result of a test part (i.e. an
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
//
// Don't inherit from TestPartResult as its destructor is not virtual.
class GTEST_API_ TestPartResult {
public:
// The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
enum Type {
kSuccess, // Succeeded.
kNonFatalFailure, // Failed but the test can continue.
kFatalFailure // Failed and the test should be terminated.
};
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
TestPartResult(Type a_type,
const char* a_file_name,
int a_line_number,
const char* a_message)
: type_(a_type),
file_name_(a_file_name == NULL ? "" : a_file_name),
line_number_(a_line_number),
summary_(ExtractSummary(a_message)),
message_(a_message) {
}
// Gets the outcome of the test part.
Type type() const { return type_; }
// Gets the name of the source file where the test part took place, or
// NULL if it's unknown.
const char* file_name() const {
return file_name_.empty() ? NULL : file_name_.c_str();
}
// Gets the line in the source file where the test part took place,
// or -1 if it's unknown.
int line_number() const { return line_number_; }
// Gets the summary of the failure message.
const char* summary() const { return summary_.c_str(); }
// Gets the message associated with the test part.
const char* message() const { return message_.c_str(); }
// Returns true iff the test part passed.
bool passed() const { return type_ == kSuccess; }
// Returns true iff the test part failed.
bool failed() const { return type_ != kSuccess; }
// Returns true iff the test part non-fatally failed.
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
// Returns true iff the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; }
private:
Type type_;
// Gets the summary of the failure message by omitting the stack
// trace in it.
static std::string ExtractSummary(const char* message);
// The name of the source file where the test part took place, or
// "" if the source file is unknown.
std::string file_name_;
// The line in the source file where the test part took place, or -1
// if the line number is unknown.
int line_number_;
std::string summary_; // The test failure summary.
std::string message_; // The test failure message.
};
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// An array of TestPartResult objects.
//
// Don't inherit from TestPartResultArray as its destructor is not
// virtual.
class GTEST_API_ TestPartResultArray {
public:
TestPartResultArray() {}
// Appends the given TestPartResult to the array.
void Append(const TestPartResult& result);
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& GetTestPartResult(int index) const;
// Returns the number of TestPartResult objects in the array.
int size() const;
private:
std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
};
// This interface knows how to report a test part result.
class TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() {}
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
};
namespace internal {
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
// statement generates new fatal failures. To do so it registers itself as the
// current test part result reporter. Besides checking if fatal failures were
// reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
class GTEST_API_ HasNewFatalFailureHelper
: public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
virtual ~HasNewFatalFailureHelper();
virtual void ReportTestPartResult(const TestPartResult& result);
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private:
bool has_new_fatal_failure_;
TestPartResultReporterInterface* original_reporter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
};
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

View File

@@ -1,259 +1,259 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// This header implements typed tests and type-parameterized tests.
// Typed (aka type-driven) tests repeat the same test for types in a
// list. You must know which types you want to test with when writing
// typed tests. Here's how you do it:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
public:
...
typedef std::list<T> List;
static T shared_;
T value_;
};
// Next, associate a list of types with the test case, which will be
// repeated for each type in the list. The typedef is necessary for
// the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes;
TYPED_TEST_CASE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// TYPED_TEST_CASE(FooTest, int);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
// tests for this test case as you want.
TYPED_TEST(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
// Since we are inside a derived class template, C++ requires use to
// visit the members of FooTest via 'this'.
TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture::
// prefix.
n += TestFixture::shared_;
// To refer to typedefs in the fixture, add the "typename
// TestFixture::" prefix.
typename TestFixture::List values;
values.push_back(n);
...
}
TYPED_TEST(FooTest, HasPropertyA) { ... }
#endif // 0
// Type-parameterized tests are abstract test patterns parameterized
// by a type. Compared with typed tests, type-parameterized tests
// allow you to define the test pattern without knowing what the type
// parameters are. The defined pattern can be instantiated with
// different types any number of times, in any number of translation
// units.
//
// If you are designing an interface or concept, you can define a
// suite of type-parameterized tests to verify properties that any
// valid implementation of the interface/concept should have. Then,
// each implementation can easily instantiate the test suite to verify
// that it conforms to the requirements, without having to write
// similar tests repeatedly. Here's an example:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
...
};
// Next, declare that you will define a type-parameterized test case
// (the _P suffix is for "parameterized" or "pattern", whichever you
// prefer):
TYPED_TEST_CASE_P(FooTest);
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
// for this type-parameterized test case as you want.
TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
TypeParam n = 0;
...
}
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
// Now the tricky part: you need to register all test patterns before
// you can instantiate them. The first argument of the macro is the
// test case name; the rest are the names of the tests in this test
// case.
REGISTER_TYPED_TEST_CASE_P(FooTest,
DoesBlah, HasPropertyA);
// Finally, you are free to instantiate the pattern with the types you
// want. If you put the above code in a header file, you can #include
// it in multiple C++ source files and instantiate it multiple times.
//
// To distinguish different instances of the pattern, the first
// argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test case name. Remember to pick unique prefixes for
// different instances.
typedef testing::Types<char, int, unsigned int> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
#endif // 0
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-type-util.h"
// Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
// given test case.
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define TYPED_TEST_CASE(CaseName, Types) \
typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
# define TYPED_TEST(CaseName, TestName) \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel< \
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
"", #CaseName, #TestName, 0); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
#endif // GTEST_HAS_TYPED_TEST
// Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
// the given type-parameterized test case are defined in. The exact
// name of the namespace is subject to change without notice.
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
gtest_case_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the variable used to remember the names of
// the defined tests in the given test case.
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
gtest_typed_test_case_p_state_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
//
// Expands to the name of the variable used to remember the names of
// the registered tests in the given test case.
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
gtest_registered_test_names_##TestCaseName##_
// The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together.
# define TYPED_TEST_CASE_P(CaseName) \
static ::testing::internal::TypedTestCasePState \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
# define TYPED_TEST_P(CaseName, TestName) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
template <typename gtest_TypeParam_> \
class TestName : public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
__FILE__, __LINE__, #CaseName, #TestName); \
} \
template <typename gtest_TypeParam_> \
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// This header implements typed tests and type-parameterized tests.
// Typed (aka type-driven) tests repeat the same test for types in a
// list. You must know which types you want to test with when writing
// typed tests. Here's how you do it:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
public:
...
typedef std::list<T> List;
static T shared_;
T value_;
};
// Next, associate a list of types with the test case, which will be
// repeated for each type in the list. The typedef is necessary for
// the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes;
TYPED_TEST_CASE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// TYPED_TEST_CASE(FooTest, int);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
// tests for this test case as you want.
TYPED_TEST(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
// Since we are inside a derived class template, C++ requires use to
// visit the members of FooTest via 'this'.
TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture::
// prefix.
n += TestFixture::shared_;
// To refer to typedefs in the fixture, add the "typename
// TestFixture::" prefix.
typename TestFixture::List values;
values.push_back(n);
...
}
TYPED_TEST(FooTest, HasPropertyA) { ... }
#endif // 0
// Type-parameterized tests are abstract test patterns parameterized
// by a type. Compared with typed tests, type-parameterized tests
// allow you to define the test pattern without knowing what the type
// parameters are. The defined pattern can be instantiated with
// different types any number of times, in any number of translation
// units.
//
// If you are designing an interface or concept, you can define a
// suite of type-parameterized tests to verify properties that any
// valid implementation of the interface/concept should have. Then,
// each implementation can easily instantiate the test suite to verify
// that it conforms to the requirements, without having to write
// similar tests repeatedly. Here's an example:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
...
};
// Next, declare that you will define a type-parameterized test case
// (the _P suffix is for "parameterized" or "pattern", whichever you
// prefer):
TYPED_TEST_CASE_P(FooTest);
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
// for this type-parameterized test case as you want.
TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
TypeParam n = 0;
...
}
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
// Now the tricky part: you need to register all test patterns before
// you can instantiate them. The first argument of the macro is the
// test case name; the rest are the names of the tests in this test
// case.
REGISTER_TYPED_TEST_CASE_P(FooTest,
DoesBlah, HasPropertyA);
// Finally, you are free to instantiate the pattern with the types you
// want. If you put the above code in a header file, you can #include
// it in multiple C++ source files and instantiate it multiple times.
//
// To distinguish different instances of the pattern, the first
// argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test case name. Remember to pick unique prefixes for
// different instances.
typedef testing::Types<char, int, unsigned int> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
#endif // 0
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-type-util.h"
// Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
// given test case.
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define TYPED_TEST_CASE(CaseName, Types) \
typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
# define TYPED_TEST(CaseName, TestName) \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel< \
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
"", #CaseName, #TestName, 0); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
#endif // GTEST_HAS_TYPED_TEST
// Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
// the given type-parameterized test case are defined in. The exact
// name of the namespace is subject to change without notice.
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
gtest_case_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the variable used to remember the names of
// the defined tests in the given test case.
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
gtest_typed_test_case_p_state_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
//
// Expands to the name of the variable used to remember the names of
// the registered tests in the given test case.
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
gtest_registered_test_names_##TestCaseName##_
// The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together.
# define TYPED_TEST_CASE_P(CaseName) \
static ::testing::internal::TypedTestCasePState \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
# define TYPED_TEST_P(CaseName, TestName) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
template <typename gtest_TypeParam_> \
class TestName : public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
__FILE__, __LINE__, #CaseName, #TestName); \
} \
template <typename gtest_TypeParam_> \
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_

View File

@@ -1,358 +1,358 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion
// macros:
//
// ASSERT_PRED_FORMAT1(pred_format, v1)
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
// ...
//
// where pred_format is a function or functor that takes n (in the
// case of ASSERT_PRED_FORMATn) values and their source expression
// text, and returns a testing::AssertionResult. See the definition
// of ASSERT_EQ in gtest.h for an example.
//
// If you don't care about formatting, you can use the more
// restrictive version:
//
// ASSERT_PRED1(pred, v1)
// ASSERT_PRED2(pred, v1, v2)
// ...
//
// where pred is an n-ary function or functor that returns bool,
// and the values v1, v2, ..., must support the << operator for
// streaming to std::ostream.
//
// We also define the EXPECT_* variations.
//
// For now we only support predicates whose arity is at most 5.
// Please email googletestframework@googlegroups.com if you need
// support for higher arities.
// GTEST_ASSERT_ is the basic statement to which all of the assertions
// in this file reduce. Don't use this in your code.
#define GTEST_ASSERT_(expression, on_failure) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar = (expression)) \
; \
else \
on_failure(gtest_ar.failure_message())
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
template <typename Pred,
typename T1>
AssertionResult AssertPred1Helper(const char* pred_text,
const char* e1,
Pred pred,
const T1& v1) {
if (pred(v1)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
GTEST_ASSERT_(pred_format(#v1, v1), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
#define GTEST_PRED1_(pred, v1, on_failure)\
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
#v1, \
pred, \
v1), on_failure)
// Unary predicate assertion macros.
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2>
AssertionResult AssertPred2Helper(const char* pred_text,
const char* e1,
const char* e2,
Pred pred,
const T1& v1,
const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
#v1, \
#v2, \
pred, \
v1, \
v2), on_failure)
// Binary predicate assertion macros.
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3>
AssertionResult AssertPred3Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
#v1, \
#v2, \
#v3, \
pred, \
v1, \
v2, \
v3), on_failure)
// Ternary predicate assertion macros.
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4>
AssertionResult AssertPred4Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
pred, \
v1, \
v2, \
v3, \
v4), on_failure)
// 4-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
AssertionResult AssertPred5Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
const char* e5,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4,
const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ", "
<< e5 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4
<< "\n" << e5 << " evaluates to " << v5;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
#v5, \
pred, \
v1, \
v2, \
v3, \
v4, \
v5), on_failure)
// 5-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion
// macros:
//
// ASSERT_PRED_FORMAT1(pred_format, v1)
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
// ...
//
// where pred_format is a function or functor that takes n (in the
// case of ASSERT_PRED_FORMATn) values and their source expression
// text, and returns a testing::AssertionResult. See the definition
// of ASSERT_EQ in gtest.h for an example.
//
// If you don't care about formatting, you can use the more
// restrictive version:
//
// ASSERT_PRED1(pred, v1)
// ASSERT_PRED2(pred, v1, v2)
// ...
//
// where pred is an n-ary function or functor that returns bool,
// and the values v1, v2, ..., must support the << operator for
// streaming to std::ostream.
//
// We also define the EXPECT_* variations.
//
// For now we only support predicates whose arity is at most 5.
// Please email googletestframework@googlegroups.com if you need
// support for higher arities.
// GTEST_ASSERT_ is the basic statement to which all of the assertions
// in this file reduce. Don't use this in your code.
#define GTEST_ASSERT_(expression, on_failure) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar = (expression)) \
; \
else \
on_failure(gtest_ar.failure_message())
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
template <typename Pred,
typename T1>
AssertionResult AssertPred1Helper(const char* pred_text,
const char* e1,
Pred pred,
const T1& v1) {
if (pred(v1)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
GTEST_ASSERT_(pred_format(#v1, v1), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
#define GTEST_PRED1_(pred, v1, on_failure)\
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
#v1, \
pred, \
v1), on_failure)
// Unary predicate assertion macros.
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2>
AssertionResult AssertPred2Helper(const char* pred_text,
const char* e1,
const char* e2,
Pred pred,
const T1& v1,
const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
#v1, \
#v2, \
pred, \
v1, \
v2), on_failure)
// Binary predicate assertion macros.
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3>
AssertionResult AssertPred3Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
#v1, \
#v2, \
#v3, \
pred, \
v1, \
v2, \
v3), on_failure)
// Ternary predicate assertion macros.
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4>
AssertionResult AssertPred4Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
pred, \
v1, \
v2, \
v3, \
v4), on_failure)
// 4-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
AssertionResult AssertPred5Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
const char* e5,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4,
const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ", "
<< e5 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4
<< "\n" << e5 << " evaluates to " << v5;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
#v5, \
pred, \
v1, \
v2, \
v3, \
v4, \
v5), on_failure)
// 5-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_

View File

@@ -1,58 +1,58 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Google C++ Testing Framework definitions useful in production code.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the
// class. For example:
//
// class MyClass {
// private:
// void MyMethod();
// FRIEND_TEST(MyClassTest, MyMethod);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
// TEST_F(MyClassTest, MyMethod) {
// // Can call MyClass::MyMethod() here.
// }
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Google C++ Testing Framework definitions useful in production code.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the
// class. For example:
//
// class MyClass {
// private:
// void MyMethod();
// FRIEND_TEST(MyClassTest, MyMethod);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
// TEST_F(MyClassTest, MyMethod) {
// // Can call MyClass::MyMethod() here.
// }
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_

View File

@@ -1,319 +1,319 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/internal/gtest-internal.h"
#include <stdio.h>
namespace testing {
namespace internal {
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
#if GTEST_HAS_DEATH_TEST
// DeathTest is a class that hides much of the complexity of the
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
// returns a concrete class that depends on the prevailing death test
// style, as defined by the --gtest_death_test_style and/or
// --gtest_internal_run_death_test flags.
// In describing the results of death tests, these terms are used with
// the corresponding definitions:
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
// if the gtest_death_test_style flag is set to an invalid value.
// The LastMessage method will return a more detailed message in that
// case. Otherwise, the DeathTest pointer pointed to by the "test"
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel {
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
// be executed immediately. OVERSEE means that the program should prepare
// the appropriate environment for a child process to execute the death
// test, then wait for it to complete.
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
// An enumeration of the three reasons that a test might be aborted.
enum AbortReason {
TEST_ENCOUNTERED_RETURN_STATEMENT,
TEST_THREW_EXCEPTION,
TEST_DID_NOT_DIE
};
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
// Waits for the death test to finish and returns its status.
virtual int Wait() = 0;
// Returns true if the death test passed; that is, the test process
// exited during the test, its exit status matches a user-supplied
// predicate, and its stderr output matches a user-supplied regular
// expression.
// The user-supplied predicate may be a macro expression rather
// than a function pointer or functor, or else Wait and Passed could
// be combined.
virtual bool Passed(bool exit_status_ok) = 0;
// Signals that the death test did not die as expected.
virtual void Abort(AbortReason reason) = 0;
// Returns a human-readable outcome message regarding the outcome of
// the last death test.
static const char* LastMessage();
static void set_last_death_test_message(const std::string& message);
private:
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
};
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test) = 0;
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
public:
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
};
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf(\
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} catch (...) { \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
# else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
// A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index),
write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
posix::Close(write_fd_);
}
const std::string& file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
int write_fd() const { return write_fd_; }
private:
std::string file_;
int line_;
int index_;
int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
};
// Returns a newly created InternalRunDeathTestFlag object with fields
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
#else // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
// death tests are not supported. Those macros must compile on such systems
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
// systems that support death tests. This allows one to write such a macro
// on a system that does not support death tests and be sure that it will
// compile on a death-test supporting system.
//
// Parameters:
// statement - A statement that a macro such as EXPECT_DEATH would test
// for program termination. This macro has to make sure this
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter iff EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
// compile inside functions where ASSERT_DEATH doesn't
// compile.
//
// The branch that has an always false condition is used to ensure that
// statement and regex are compiled (and thus syntactically correct) but
// never executed. The unreachable code macro protects the terminator
// statement from generating an 'unreachable code' warning in case
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#endif // GTEST_HAS_DEATH_TEST
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/internal/gtest-internal.h"
#include <stdio.h>
namespace testing {
namespace internal {
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
#if GTEST_HAS_DEATH_TEST
// DeathTest is a class that hides much of the complexity of the
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
// returns a concrete class that depends on the prevailing death test
// style, as defined by the --gtest_death_test_style and/or
// --gtest_internal_run_death_test flags.
// In describing the results of death tests, these terms are used with
// the corresponding definitions:
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
// if the gtest_death_test_style flag is set to an invalid value.
// The LastMessage method will return a more detailed message in that
// case. Otherwise, the DeathTest pointer pointed to by the "test"
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel {
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
// be executed immediately. OVERSEE means that the program should prepare
// the appropriate environment for a child process to execute the death
// test, then wait for it to complete.
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
// An enumeration of the three reasons that a test might be aborted.
enum AbortReason {
TEST_ENCOUNTERED_RETURN_STATEMENT,
TEST_THREW_EXCEPTION,
TEST_DID_NOT_DIE
};
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
// Waits for the death test to finish and returns its status.
virtual int Wait() = 0;
// Returns true if the death test passed; that is, the test process
// exited during the test, its exit status matches a user-supplied
// predicate, and its stderr output matches a user-supplied regular
// expression.
// The user-supplied predicate may be a macro expression rather
// than a function pointer or functor, or else Wait and Passed could
// be combined.
virtual bool Passed(bool exit_status_ok) = 0;
// Signals that the death test did not die as expected.
virtual void Abort(AbortReason reason) = 0;
// Returns a human-readable outcome message regarding the outcome of
// the last death test.
static const char* LastMessage();
static void set_last_death_test_message(const std::string& message);
private:
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
};
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test) = 0;
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
public:
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
};
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf(\
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} catch (...) { \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
# else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
// A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index),
write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
posix::Close(write_fd_);
}
const std::string& file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
int write_fd() const { return write_fd_; }
private:
std::string file_;
int line_;
int index_;
int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
};
// Returns a newly created InternalRunDeathTestFlag object with fields
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
#else // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
// death tests are not supported. Those macros must compile on such systems
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
// systems that support death tests. This allows one to write such a macro
// on a system that does not support death tests and be sure that it will
// compile on a death-test supporting system.
//
// Parameters:
// statement - A statement that a macro such as EXPECT_DEATH would test
// for program termination. This macro has to make sure this
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter iff EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
// compile inside functions where ASSERT_DEATH doesn't
// compile.
//
// The branch that has an always false condition is used to ensure that
// statement and regex are compiled (and thus syntactically correct) but
// never executed. The unreachable code macro protects the terminator
// statement from generating an 'unreachable code' warning in case
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#endif // GTEST_HAS_DEATH_TEST
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_

View File

@@ -1,206 +1,206 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: keith.ray@gmail.com (Keith Ray)
//
// Google Test filepath utilities
//
// This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included in <gtest/internal/gtest-internal.h>.
// Do not include this header file separately!
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
// FilePath - a class for file and directory pathname manipulation which
// handles platform-specific conventions (like the pathname separator).
// Used for helper functions for naming files in a directory for xml output.
// Except for Set methods, all methods are const or static, which provides an
// "immutable value object" -- useful for peace of mind.
// A FilePath with a value ending in a path separator ("like/this/") represents
// a directory, otherwise it is assumed to represent a file. In either case,
// it may or may not represent an actual file or directory in the file system.
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize();
}
FilePath& operator=(const FilePath& rhs) {
Set(rhs);
return *this;
}
void Set(const FilePath& rhs) {
pathname_ = rhs.pathname_;
}
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
// Returns the current working directory, or "" if unsuccessful.
static FilePath GetCurrentDir();
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension);
// Given directory = "dir", relative_path = "test.xml",
// returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
static FilePath ConcatPaths(const FilePath& directory,
const FilePath& relative_path);
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
static FilePath GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension);
// Returns true iff the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath RemoveTrailingPathSeparator() const;
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveDirectoryName() const;
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveFileName() const;
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath RemoveExtension(const char* extension) const;
// Creates directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create
// directories for any reason. Will also return false if the FilePath does
// not represent a directory (that is, it doesn't end with a path separator).
bool CreateDirectoriesRecursively() const;
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool CreateFolder() const;
// Returns true if FilePath describes something in the file-system,
// either a file, directory, or whatever, and that something exists.
bool FileOrDirectoryExists() const;
// Returns true if pathname describes a directory in the file-system
// that exists.
bool DirectoryExists() const;
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool IsDirectory() const;
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool IsRootDirectory() const;
// Returns true if pathname describes an absolute path.
bool IsAbsolutePath() const;
private:
// Replaces multiple consecutive separators with a single separator.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
//
// A pathname with multiple consecutive separators may occur either through
// user error or as a result of some scripts or APIs that generate a pathname
// with a trailing separator. On other platforms the same API or script
// may NOT generate a pathname with a trailing "/". Then elsewhere that
// pathname may have another "/" and pathname components added to it,
// without checking for the separator already being there.
// The script language and operating system may allow paths like "foo//bar"
// but some of the functions in FilePath will not handle that correctly. In
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
//
// On Windows this method also replaces the alternate path separator '/' with
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
// "bar\\foo".
void Normalize();
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
std::string pathname_;
}; // class FilePath
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: keith.ray@gmail.com (Keith Ray)
//
// Google Test filepath utilities
//
// This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included in <gtest/internal/gtest-internal.h>.
// Do not include this header file separately!
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
// FilePath - a class for file and directory pathname manipulation which
// handles platform-specific conventions (like the pathname separator).
// Used for helper functions for naming files in a directory for xml output.
// Except for Set methods, all methods are const or static, which provides an
// "immutable value object" -- useful for peace of mind.
// A FilePath with a value ending in a path separator ("like/this/") represents
// a directory, otherwise it is assumed to represent a file. In either case,
// it may or may not represent an actual file or directory in the file system.
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize();
}
FilePath& operator=(const FilePath& rhs) {
Set(rhs);
return *this;
}
void Set(const FilePath& rhs) {
pathname_ = rhs.pathname_;
}
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
// Returns the current working directory, or "" if unsuccessful.
static FilePath GetCurrentDir();
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension);
// Given directory = "dir", relative_path = "test.xml",
// returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
static FilePath ConcatPaths(const FilePath& directory,
const FilePath& relative_path);
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
static FilePath GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension);
// Returns true iff the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath RemoveTrailingPathSeparator() const;
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveDirectoryName() const;
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveFileName() const;
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath RemoveExtension(const char* extension) const;
// Creates directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create
// directories for any reason. Will also return false if the FilePath does
// not represent a directory (that is, it doesn't end with a path separator).
bool CreateDirectoriesRecursively() const;
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool CreateFolder() const;
// Returns true if FilePath describes something in the file-system,
// either a file, directory, or whatever, and that something exists.
bool FileOrDirectoryExists() const;
// Returns true if pathname describes a directory in the file-system
// that exists.
bool DirectoryExists() const;
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool IsDirectory() const;
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool IsRootDirectory() const;
// Returns true if pathname describes an absolute path.
bool IsAbsolutePath() const;
private:
// Replaces multiple consecutive separators with a single separator.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
//
// A pathname with multiple consecutive separators may occur either through
// user error or as a result of some scripts or APIs that generate a pathname
// with a trailing separator. On other platforms the same API or script
// may NOT generate a pathname with a trailing "/". Then elsewhere that
// pathname may have another "/" and pathname components added to it,
// without checking for the separator already being there.
// The script language and operating system may allow paths like "foo//bar"
// but some of the functions in FilePath will not handle that correctly. In
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
//
// On Windows this method also replaces the alternate path separator '/' with
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
// "bar\\foo".
void Normalize();
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
std::string pathname_;
}; // class FilePath
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_

View File

@@ -1,233 +1,233 @@
// Copyright 2003 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Dan Egnor (egnor@google.com)
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is assigned, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Bill Gibbons suggested we use something like this.
//
// Thread Safety:
// Unlike other linked_ptr implementations, in this implementation
// a linked_ptr object is thread-safe in the sense that:
// - it's safe to copy linked_ptr objects concurrently,
// - it's safe to copy *from* a linked_ptr and read its underlying
// raw pointer (e.g. via get()) concurrently, and
// - it's safe to write to two linked_ptrs that point to the same
// shared object concurrently.
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
// confusion with normal linked_ptr.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#include <stdlib.h>
#include <assert.h>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
void join(linked_ptr_internal const* ptr)
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
bool depart()
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
// Copyright 2003 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Dan Egnor (egnor@google.com)
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is assigned, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Bill Gibbons suggested we use something like this.
//
// Thread Safety:
// Unlike other linked_ptr implementations, in this implementation
// a linked_ptr object is thread-safe in the sense that:
// - it's safe to copy linked_ptr objects concurrently,
// - it's safe to copy *from* a linked_ptr and read its underlying
// raw pointer (e.g. via get()) concurrently, and
// - it's safe to write to two linked_ptrs that point to the same
// shared object concurrently.
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
// confusion with normal linked_ptr.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#include <stdlib.h>
#include <assert.h>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
void join(linked_ptr_internal const* ptr)
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
bool depart()
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_

View File

@@ -1,301 +1,301 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most $n arguments in Values,
// and at most $maxtuple arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tuple which is
// currently set at $maxtuple.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Forward declarations of ValuesIn(), which is implemented in
// include/gtest/gtest-param-test.h.
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end);
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container);
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray1& other);
const T1 v1_;
};
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ValueArray$i {
public:
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
return ValuesIn(array);
}
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray$i& other);
$for j [[
const T$j v$(j)_;
]]
};
]]
# if GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
class CartesianProductGenerator$i
: public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > {
public:
typedef ::testing::tuple<$for j, [[T$j]]> ParamType;
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
virtual ~CartesianProductGenerator$i() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
const ParamGenerator<T$j>& g$j,
const typename ParamGenerator<T$j>::iterator& current$(j)]])
: base_(base),
$for j, [[
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
]] {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current$(i)_;
$for k [[
if (current$(i+2-k)_ == end$(i+2-k)_) {
current$(i+2-k)_ = begin$(i+2-k)_;
++current$(i+2-k-1)_;
}
]]
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
($for j && [[
current$(j)_ == typed_other->current$(j)_
]]);
}
private:
Iterator(const Iterator& other)
: base_(other.base_), $for j, [[
begin$(j)_(other.begin$(j)_),
end$(j)_(other.end$(j)_),
current$(j)_(other.current$(j)_)
]] {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType($for j, [[*current$(j)_]]);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
$for j || [[
current$(j)_ == end$(j)_
]];
}
// No implementation - assignment is unsupported.
void operator=(const Iterator& other);
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
$for j [[
const typename ParamGenerator<T$j>::iterator begin$(j)_;
const typename ParamGenerator<T$j>::iterator end$(j)_;
typename ParamGenerator<T$j>::iterator current$(j)_;
]]
ParamType current_value_;
}; // class CartesianProductGenerator$i::Iterator
// No implementation - assignment is unsupported.
void operator=(const CartesianProductGenerator$i& other);
$for j [[
const ParamGenerator<T$j> g$(j)_;
]]
}; // class CartesianProductGenerator$i
]]
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[class Generator$j]]>
class CartesianProductHolder$i {
public:
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
template <$for j, [[typename T$j]]>
operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const {
return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >(
new CartesianProductGenerator$i<$for j, [[T$j]]>(
$for j,[[
static_cast<ParamGenerator<T$j> >(g$(j)_)
]]));
}
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder$i& other);
$for j [[
const Generator$j g$(j)_;
]]
}; // class CartesianProductHolder$i
]]
# endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most $n arguments in Values,
// and at most $maxtuple arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tr1::tuple which is
// currently set at $maxtuple.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Forward declarations of ValuesIn(), which is implemented in
// include/gtest/gtest-param-test.h.
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end);
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container);
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray1& other);
const T1 v1_;
};
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ValueArray$i {
public:
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
return ValuesIn(array);
}
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray$i& other);
$for j [[
const T$j v$(j)_;
]]
};
]]
# if GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
class CartesianProductGenerator$i
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
public:
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
virtual ~CartesianProductGenerator$i() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
const ParamGenerator<T$j>& g$j,
const typename ParamGenerator<T$j>::iterator& current$(j)]])
: base_(base),
$for j, [[
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
]] {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current$(i)_;
$for k [[
if (current$(i+2-k)_ == end$(i+2-k)_) {
current$(i+2-k)_ = begin$(i+2-k)_;
++current$(i+2-k-1)_;
}
]]
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
($for j && [[
current$(j)_ == typed_other->current$(j)_
]]);
}
private:
Iterator(const Iterator& other)
: base_(other.base_), $for j, [[
begin$(j)_(other.begin$(j)_),
end$(j)_(other.end$(j)_),
current$(j)_(other.current$(j)_)
]] {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType($for j, [[*current$(j)_]]);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
$for j || [[
current$(j)_ == end$(j)_
]];
}
// No implementation - assignment is unsupported.
void operator=(const Iterator& other);
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
$for j [[
const typename ParamGenerator<T$j>::iterator begin$(j)_;
const typename ParamGenerator<T$j>::iterator end$(j)_;
typename ParamGenerator<T$j>::iterator current$(j)_;
]]
ParamType current_value_;
}; // class CartesianProductGenerator$i::Iterator
// No implementation - assignment is unsupported.
void operator=(const CartesianProductGenerator$i& other);
$for j [[
const ParamGenerator<T$j> g$(j)_;
]]
}; // class CartesianProductGenerator$i
]]
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[class Generator$j]]>
class CartesianProductHolder$i {
public:
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
template <$for j, [[typename T$j]]>
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
new CartesianProductGenerator$i<$for j, [[T$j]]>(
$for j,[[
static_cast<ParamGenerator<T$j> >(g$(j)_)
]]));
}
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder$i& other);
$for j [[
const Generator$j g$(j)_;
]]
}; // class CartesianProductHolder$i
]]
# endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_

View File

@@ -1,167 +1,167 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file declares the String class and functions used internally by
// Google Test. They are subject to change without notice. They should not used
// by code external to Google Test.
//
// This header file is #included by <gtest/internal/gtest-internal.h>.
// It should not be #included by other files.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h>
#endif
#include <string.h>
#include <string>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// String - an abstract class holding static string utilities.
class GTEST_API_ String {
public:
// Static utility methods
// Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is
// NULL.
//
// This is different from strdup() in string.h, which allocates
// memory using malloc().
static const char* CloneCString(const char* c_str);
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
//
// The wide string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static LPCWSTR AnsiToUtf16(const char* c_str);
// Creates an ANSI string from the given wide string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
//
// The returned string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif
// Compares two C strings. Returns true iff they have the same content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CStringEquals(const char* lhs, const char* rhs);
// Converts a wide C string to a String using the UTF-8 encoding.
// NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same
// content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
private:
String(); // Not meant to be instantiated.
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file declares the String class and functions used internally by
// Google Test. They are subject to change without notice. They should not used
// by code external to Google Test.
//
// This header file is #included by <gtest/internal/gtest-internal.h>.
// It should not be #included by other files.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h>
#endif
#include <string.h>
#include <string>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// String - an abstract class holding static string utilities.
class GTEST_API_ String {
public:
// Static utility methods
// Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is
// NULL.
//
// This is different from strdup() in string.h, which allocates
// memory using malloc().
static const char* CloneCString(const char* c_str);
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
//
// The wide string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static LPCWSTR AnsiToUtf16(const char* c_str);
// Creates an ANSI string from the given wide string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
//
// The returned string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif
// Compares two C strings. Returns true iff they have the same content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CStringEquals(const char* lhs, const char* rhs);
// Converts a wide C string to a String using the UTF-8 encoding.
// NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same
// content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
private:
String(); // Not meant to be instantiated.
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_

View File

@@ -1,347 +1,339 @@
$$ -*- mode: c++; -*-
$var n = 10 $$ Maximum number of tuple fields we want to support.
$$ This meta comment fixes auto-indentation in Emacs. }}
// Copyright 2009 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#include <utility> // For ::std::pair.
// The compiler used in Symbian has a bug that prevents us from declaring the
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
// Sun Studio versions < 12 also have the above bug.
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
private:
#endif
// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
// with our own definitions. Therefore using our own tuple does not work on
// those compilers.
#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
#endif
$range i 0..n-1
$range j 0..n
$range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
$for k [[
$range m 0..k-1
$range m2 k..n-1
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
]]
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
]]
// In theory, defining stuff in the ::std namespace is undefined
// behavior. We can do this as we are playing the role of a standard
// library vendor.
namespace std {
namespace tr1 {
template <$for i, [[typename T$i = void]]>
class tuple;
// Anything in namespace gtest_internal is Google Test's INTERNAL
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
namespace gtest_internal {
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
template <typename T>
struct ByRef { typedef const T& type; }; // NOLINT
template <typename T>
struct ByRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for ByRef.
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
// is the same as tr1::add_reference<T>::type.
template <typename T>
struct AddRef { typedef T& type; }; // NOLINT
template <typename T>
struct AddRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for AddRef.
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
// A helper for implementing get<k>().
template <int k> class Get;
// A helper for implementing tuple_element<k, T>. kIndexValid is true
// iff k < the number of fields in tuple type T.
template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement;
$for i [[
template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
typedef T$i type;
};
]]
} // namespace gtest_internal
template <>
class tuple<> {
public:
tuple() {}
tuple(const tuple& /* t */) {}
tuple& operator=(const tuple& /* t */) { return *this; }
};
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
tuple() : $for m, [[f$(m)_()]] {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {}
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
template <GTEST_$(k)_TYPENAMES_(U)>
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
$if k == 2 [[
template <typename U0, typename U1>
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
]]
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
return CopyFrom(t);
}
$if k == 2 [[
template <typename U0, typename U1>
tuple& operator=(const ::std::pair<U0, U1>& p) {
f0_ = p.first;
f1_ = p.second;
return *this;
}
]]
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
$for m [[
f$(m)_ = t.f$(m)_;
]]
return *this;
}
$for m [[
T$m f$(m)_;
]]
};
]]
// 6.1.3.2 Tuple creation functions.
// Known limitations: we don't support passing an
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
// implement tie().
inline tuple<> make_tuple() { return tuple<>(); }
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
}
]]
// 6.1.3.3 Tuple helper classes.
template <typename Tuple> struct tuple_size;
$for j [[
template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
static const int value = $j;
};
]]
template <int k, class Tuple>
struct tuple_element {
typedef typename gtest_internal::TupleElement<
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
};
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
// 6.1.3.4 Element access.
namespace gtest_internal {
$for i [[
template <>
class Get<$i> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
ConstField(const Tuple& t) { return t.f$(i)_; }
};
]]
} // namespace gtest_internal
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::Field(t);
}
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(const GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::ConstField(t);
}
// 6.1.3.5 Relational operators
// We only implement == and !=, as we don't have a need for the rest yet.
namespace gtest_internal {
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
// first k fields of t1 equals the first k fields of t2.
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
// k1 != k2.
template <int kSize1, int kSize2>
struct SameSizeTuplePrefixComparator;
template <>
struct SameSizeTuplePrefixComparator<0, 0> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
return true;
}
};
template <int k>
struct SameSizeTuplePrefixComparator<k, k> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
}
};
} // namespace gtest_internal
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
}
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
// 6.1.4 Pairs.
// Unimplemented.
} // namespace tr1
} // namespace std
$for j [[
#undef GTEST_$(j)_TUPLE_
]]
$for j [[
#undef GTEST_$(j)_TYPENAMES_
]]
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
$$ -*- mode: c++; -*-
$var n = 10 $$ Maximum number of tuple fields we want to support.
$$ This meta comment fixes auto-indentation in Emacs. }}
// Copyright 2009 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#include <utility> // For ::std::pair.
// The compiler used in Symbian has a bug that prevents us from declaring the
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
// Sun Studio versions < 12 also have the above bug.
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
private:
#endif
$range i 0..n-1
$range j 0..n
$range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
$for k [[
$range m 0..k-1
$range m2 k..n-1
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
]]
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
]]
// In theory, defining stuff in the ::std namespace is undefined
// behavior. We can do this as we are playing the role of a standard
// library vendor.
namespace std {
namespace tr1 {
template <$for i, [[typename T$i = void]]>
class tuple;
// Anything in namespace gtest_internal is Google Test's INTERNAL
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
namespace gtest_internal {
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
template <typename T>
struct ByRef { typedef const T& type; }; // NOLINT
template <typename T>
struct ByRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for ByRef.
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
// is the same as tr1::add_reference<T>::type.
template <typename T>
struct AddRef { typedef T& type; }; // NOLINT
template <typename T>
struct AddRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for AddRef.
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
// A helper for implementing get<k>().
template <int k> class Get;
// A helper for implementing tuple_element<k, T>. kIndexValid is true
// iff k < the number of fields in tuple type T.
template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement;
$for i [[
template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
typedef T$i type;
};
]]
} // namespace gtest_internal
template <>
class tuple<> {
public:
tuple() {}
tuple(const tuple& /* t */) {}
tuple& operator=(const tuple& /* t */) { return *this; }
};
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
tuple() : $for m, [[f$(m)_()]] {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {}
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
template <GTEST_$(k)_TYPENAMES_(U)>
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
$if k == 2 [[
template <typename U0, typename U1>
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
]]
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
return CopyFrom(t);
}
$if k == 2 [[
template <typename U0, typename U1>
tuple& operator=(const ::std::pair<U0, U1>& p) {
f0_ = p.first;
f1_ = p.second;
return *this;
}
]]
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
$for m [[
f$(m)_ = t.f$(m)_;
]]
return *this;
}
$for m [[
T$m f$(m)_;
]]
};
]]
// 6.1.3.2 Tuple creation functions.
// Known limitations: we don't support passing an
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
// implement tie().
inline tuple<> make_tuple() { return tuple<>(); }
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
}
]]
// 6.1.3.3 Tuple helper classes.
template <typename Tuple> struct tuple_size;
$for j [[
template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
static const int value = $j;
};
]]
template <int k, class Tuple>
struct tuple_element {
typedef typename gtest_internal::TupleElement<
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
};
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
// 6.1.3.4 Element access.
namespace gtest_internal {
$for i [[
template <>
class Get<$i> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
ConstField(const Tuple& t) { return t.f$(i)_; }
};
]]
} // namespace gtest_internal
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::Field(t);
}
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(const GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::ConstField(t);
}
// 6.1.3.5 Relational operators
// We only implement == and !=, as we don't have a need for the rest yet.
namespace gtest_internal {
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
// first k fields of t1 equals the first k fields of t2.
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
// k1 != k2.
template <int kSize1, int kSize2>
struct SameSizeTuplePrefixComparator;
template <>
struct SameSizeTuplePrefixComparator<0, 0> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
return true;
}
};
template <int k>
struct SameSizeTuplePrefixComparator<k, k> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
}
};
} // namespace gtest_internal
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
}
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
// 6.1.4 Pairs.
// Unimplemented.
} // namespace tr1
} // namespace std
$for j [[
#undef GTEST_$(j)_TUPLE_
]]
$for j [[
#undef GTEST_$(j)_TYPENAMES_
]]
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_

View File

@@ -1,297 +1,297 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of type lists we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently we support at most $n types in a list, and at most $n
// type-parameterized tests in one type-parameterized test case.
// Please contact googletestframework@googlegroups.com if you need
// more.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_
# include <cxxabi.h>
# elif defined(__HP_aCC)
# include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_
namespace testing {
namespace internal {
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it.
# if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
return name_str;
# else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else
return "<type>";
# endif // GTEST_HAS_RTTI
}
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
// type. This can be used as a compile-time assertion to ensure that
// two types are equal.
template <typename T1, typename T2>
struct AssertTypeEq;
template <typename T>
struct AssertTypeEq<T, T> {
typedef bool type;
};
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
// support directly.
struct None {};
// The following family of struct and struct templates are used to
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
// represents a type list with N types (T1, T2, ..., and TN) in it.
// Except for Types0, every struct in the family has two member types:
// Head for the first type in the list, and Tail for the rest of the
// list.
// The empty type list.
struct Types0 {};
// Type lists of length 1, 2, 3, and so on.
template <typename T1>
struct Types1 {
typedef T1 Head;
typedef Types0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
struct Types$i {
typedef T1 Head;
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
};
]]
} // namespace internal
// We don't want to require the users to write TypesN<...> directly,
// as that would require them to count the length. Types<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Types<int>
// will appear as Types<int, None, None, ..., None> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Types<T1, ..., TN>, and Google Test will translate
// that to TypesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Types template.
$range i 1..n
template <$for i, [[typename T$i = internal::None]]>
struct Types {
typedef internal::Types$n<$for i, [[T$i]]> type;
};
template <>
struct Types<$for i, [[internal::None]]> {
typedef internal::Types0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[typename T$j]]>
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
typedef internal::Types$i<$for j, [[T$j]]> type;
};
]]
namespace internal {
# define GTEST_TEMPLATE_ template <typename T> class
// The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
// as the type Tmpl<T>. This allows us to actually instantiate the
// template "selected" by TemplateSel<Tmpl>.
//
// This trick is necessary for simulating typedef for class templates,
// which C++ doesn't support directly.
template <GTEST_TEMPLATE_ Tmpl>
struct TemplateSel {
template <typename T>
struct Bind {
typedef Tmpl<T> type;
};
};
# define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type
// A unique struct template used as the default value for the
// arguments of class template Templates. This allows us to simulate
// variadic templates (e.g. Templates<int>, Templates<int, double>,
// and etc), which C++ doesn't support directly.
template <typename T>
struct NoneT {};
// The following family of struct and struct templates are used to
// represent template lists. In particular, TemplatesN<T1, T2, ...,
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
// for Templates0, every struct in the family has two member types:
// Head for the selector of the first template in the list, and Tail
// for the rest of the list.
// The empty template list.
struct Templates0 {};
// Template lists of length 1, 2, 3, and so on.
template <GTEST_TEMPLATE_ T1>
struct Templates1 {
typedef TemplateSel<T1> Head;
typedef Templates0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates$i {
typedef TemplateSel<T1> Head;
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
};
]]
// We don't want to require the users to write TemplatesN<...> directly,
// as that would require them to count the length. Templates<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Templates<list>
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Templates<T1, ..., TN>, and Google Test will translate
// that to TemplatesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Templates template.
$range i 1..n
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
struct Templates {
typedef Templates$n<$for i, [[T$i]]> type;
};
template <>
struct Templates<$for i, [[NoneT]]> {
typedef Templates0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
typedef Templates$i<$for j, [[T$j]]> type;
};
]]
// The TypeList template makes it possible to use either a single type
// or a Types<...> list in TYPED_TEST_CASE() and
// INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T>
struct TypeList {
typedef Types1<T> type;
};
$range i 1..n
template <$for i, [[typename T$i]]>
struct TypeList<Types<$for i, [[T$i]]> > {
typedef typename Types<$for i, [[T$i]]>::type type;
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of type lists we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently we support at most $n types in a list, and at most $n
// type-parameterized tests in one type-parameterized test case.
// Please contact googletestframework@googlegroups.com if you need
// more.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_
# include <cxxabi.h>
# elif defined(__HP_aCC)
# include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_
namespace testing {
namespace internal {
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it.
# if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
return name_str;
# else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else
return "<type>";
# endif // GTEST_HAS_RTTI
}
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
// type. This can be used as a compile-time assertion to ensure that
// two types are equal.
template <typename T1, typename T2>
struct AssertTypeEq;
template <typename T>
struct AssertTypeEq<T, T> {
typedef bool type;
};
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
// support directly.
struct None {};
// The following family of struct and struct templates are used to
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
// represents a type list with N types (T1, T2, ..., and TN) in it.
// Except for Types0, every struct in the family has two member types:
// Head for the first type in the list, and Tail for the rest of the
// list.
// The empty type list.
struct Types0 {};
// Type lists of length 1, 2, 3, and so on.
template <typename T1>
struct Types1 {
typedef T1 Head;
typedef Types0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
struct Types$i {
typedef T1 Head;
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
};
]]
} // namespace internal
// We don't want to require the users to write TypesN<...> directly,
// as that would require them to count the length. Types<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Types<int>
// will appear as Types<int, None, None, ..., None> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Types<T1, ..., TN>, and Google Test will translate
// that to TypesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Types template.
$range i 1..n
template <$for i, [[typename T$i = internal::None]]>
struct Types {
typedef internal::Types$n<$for i, [[T$i]]> type;
};
template <>
struct Types<$for i, [[internal::None]]> {
typedef internal::Types0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[typename T$j]]>
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
typedef internal::Types$i<$for j, [[T$j]]> type;
};
]]
namespace internal {
# define GTEST_TEMPLATE_ template <typename T> class
// The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
// as the type Tmpl<T>. This allows us to actually instantiate the
// template "selected" by TemplateSel<Tmpl>.
//
// This trick is necessary for simulating typedef for class templates,
// which C++ doesn't support directly.
template <GTEST_TEMPLATE_ Tmpl>
struct TemplateSel {
template <typename T>
struct Bind {
typedef Tmpl<T> type;
};
};
# define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type
// A unique struct template used as the default value for the
// arguments of class template Templates. This allows us to simulate
// variadic templates (e.g. Templates<int>, Templates<int, double>,
// and etc), which C++ doesn't support directly.
template <typename T>
struct NoneT {};
// The following family of struct and struct templates are used to
// represent template lists. In particular, TemplatesN<T1, T2, ...,
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
// for Templates0, every struct in the family has two member types:
// Head for the selector of the first template in the list, and Tail
// for the rest of the list.
// The empty template list.
struct Templates0 {};
// Template lists of length 1, 2, 3, and so on.
template <GTEST_TEMPLATE_ T1>
struct Templates1 {
typedef TemplateSel<T1> Head;
typedef Templates0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates$i {
typedef TemplateSel<T1> Head;
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
};
]]
// We don't want to require the users to write TemplatesN<...> directly,
// as that would require them to count the length. Templates<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Templates<list>
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Templates<T1, ..., TN>, and Google Test will translate
// that to TemplatesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Templates template.
$range i 1..n
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
struct Templates {
typedef Templates$n<$for i, [[T$i]]> type;
};
template <>
struct Templates<$for i, [[NoneT]]> {
typedef Templates0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
typedef Templates$i<$for j, [[T$j]]> type;
};
]]
// The TypeList template makes it possible to use either a single type
// or a Types<...> list in TYPED_TEST_CASE() and
// INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T>
struct TypeList {
typedef Types1<T> type;
};
$range i 1..n
template <$for i, [[typename T$i]]>
struct TypeList<Types<$for i, [[T$i]]> > {
typedef typename Types<$for i, [[T$i]]>::type type;
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_

View File

@@ -1,48 +1,48 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// Google C++ Testing Framework (Google Test)
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
// This line ensures that gtest.h can be compiled on its own, even
// when it's fused.
#include "gtest/gtest.h"
// The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
#include "src/gtest-port.cc"
#include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc"
#include "src/gtest-typed-test.cc"
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// Google C++ Testing Framework (Google Test)
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
// This line ensures that gtest.h can be compiled on its own, even
// when it's fused.
#include "gtest/gtest.h"
// The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
#include "src/gtest-port.cc"
#include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc"
#include "src/gtest-typed-test.cc"

View File

@@ -1,380 +1,382 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"
#include <stdlib.h>
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
# include <io.h>
#elif GTEST_OS_SYMBIAN
// Symbian OpenC has PATH_MAX in sys/syslimits.h
# include <sys/syslimits.h>
#else
# include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE
#if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX)
# define GTEST_PATH_MAX_ PATH_MAX
#elif defined(_XOPEN_PATH_MAX)
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
#else
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
#if GTEST_OS_WINDOWS
// On Windows, '\\' is the standard path separator, but many tools and the
// Windows API also accept '/' as an alternate path separator. Unless otherwise
// noted, a file path can contain either kind of path separators, or a mixture
// of them.
const char kPathSeparator = '\\';
const char kAlternatePathSeparator = '/';
const char kAlternatePathSeparatorString[] = "/";
# if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory. You should not use
// the current directory in tests on Windows CE, but this at least
// provides a reasonable fallback.
const char kCurrentDirectoryString[] = "\\";
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
const DWORD kInvalidFileAttributes = 0xffffffff;
# else
const char kCurrentDirectoryString[] = ".\\";
# endif // GTEST_OS_WINDOWS_MOBILE
#else
const char kPathSeparator = '/';
const char kCurrentDirectoryString[] = "./";
#endif // GTEST_OS_WINDOWS
// Returns whether the given character is a valid path separator.
static bool IsPathSeparator(char c) {
#if GTEST_HAS_ALT_PATH_SEP_
return (c == kPathSeparator) || (c == kAlternatePathSeparator);
#else
return c == kPathSeparator;
#endif
}
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
// Windows CE doesn't have a current directory, so we just return
// something reasonable.
return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
#else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE
}
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath FilePath::RemoveExtension(const char* extension) const {
const std::string dot_extension = std::string(".") + extension;
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
return FilePath(pathname_.substr(
0, pathname_.length() - dot_extension.length()));
}
return *this;
}
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FilePath::FindLastPathSeparator() const {
const char* const last_sep = strrchr(c_str(), kPathSeparator);
#if GTEST_HAS_ALT_PATH_SEP_
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
// Comparing two pointers of which only one is NULL is undefined.
if (last_alt_sep != NULL &&
(last_sep == NULL || last_alt_sep > last_sep)) {
return last_alt_sep;
}
#endif
return last_sep;
}
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveDirectoryName() const {
const char* const last_sep = FindLastPathSeparator();
return last_sep ? FilePath(last_sep + 1) : *this;
}
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveFileName() const {
const char* const last_sep = FindLastPathSeparator();
std::string dir;
if (last_sep) {
dir = std::string(c_str(), last_sep + 1 - c_str());
} else {
dir = kCurrentDirectoryString;
}
return FilePath(dir);
}
// Helper functions for naming files in a directory for xml output.
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
FilePath FilePath::MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension) {
std::string file;
if (number == 0) {
file = base_name.string() + "." + extension;
} else {
file = base_name.string() + "_" + StreamableToString(number)
+ "." + extension;
}
return ConcatPaths(directory, FilePath(file));
}
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
FilePath FilePath::ConcatPaths(const FilePath& directory,
const FilePath& relative_path) {
if (directory.IsEmpty())
return relative_path;
const FilePath dir(directory.RemoveTrailingPathSeparator());
return FilePath(dir.string() + kPathSeparator + relative_path.string());
}
// Returns true if pathname describes something findable in the file-system,
// either a file, directory, or whatever.
bool FilePath::FileOrDirectoryExists() const {
#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
return attributes != kInvalidFileAttributes;
#else
posix::StatStruct file_stat;
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
#endif // GTEST_OS_WINDOWS_MOBILE
}
// Returns true if pathname describes a directory in the file-system
// that exists.
bool FilePath::DirectoryExists() const {
bool result = false;
#if GTEST_OS_WINDOWS
// Don't strip off trailing separator if path is a root directory on
// Windows (like "C:\\").
const FilePath& path(IsRootDirectory() ? *this :
RemoveTrailingPathSeparator());
#else
const FilePath& path(*this);
#endif
#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
if ((attributes != kInvalidFileAttributes) &&
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
result = true;
}
#else
posix::StatStruct file_stat;
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE
return result;
}
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS
// TODO(wan@google.com): on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
#endif
}
// Returns true if pathname describes an absolute path.
bool FilePath::IsAbsolutePath() const {
const char* const name = pathname_.c_str();
#if GTEST_OS_WINDOWS
return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' &&
IsPathSeparator(name[2]);
#else
return IsPathSeparator(name[0]);
#endif
}
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension) {
FilePath full_pathname;
int number = 0;
do {
full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
} while (full_pathname.FileOrDirectoryExists());
return full_pathname;
}
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool FilePath::IsDirectory() const {
return !pathname_.empty() &&
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
}
// Create directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create directories
// for any reason.
bool FilePath::CreateDirectoriesRecursively() const {
if (!this->IsDirectory()) {
return false;
}
if (pathname_.length() == 0 || this->DirectoryExists()) {
return true;
}
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
return parent.CreateDirectoriesRecursively() && this->CreateFolder();
}
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool FilePath::CreateFolder() const {
#if GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
int result = CreateDirectory(unicode, NULL) ? 0 : -1;
delete [] unicode;
#elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str());
#else
int result = mkdir(pathname_.c_str(), 0777);
#endif // GTEST_OS_WINDOWS_MOBILE
if (result == -1) {
return this->DirectoryExists(); // An error is OK if the directory exists.
}
return true; // No error.
}
// If input name has a trailing separator character, remove it and return the
// name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const {
return IsDirectory()
? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this;
}
// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
if (pathname_.c_str() == NULL) {
pathname_ = "";
return;
}
const char* src = pathname_.c_str();
char* const dest = new char[pathname_.length() + 1];
char* dest_ptr = dest;
memset(dest_ptr, 0, pathname_.length() + 1);
while (*src != '\0') {
*dest_ptr = *src;
if (!IsPathSeparator(*src)) {
src++;
} else {
#if GTEST_HAS_ALT_PATH_SEP_
if (*dest_ptr == kAlternatePathSeparator) {
*dest_ptr = kPathSeparator;
}
#endif
while (IsPathSeparator(*src))
src++;
}
dest_ptr++;
}
*dest_ptr = '\0';
pathname_ = dest;
delete[] dest;
}
} // namespace internal
} // namespace testing
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"
#include <stdlib.h>
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
# include <io.h>
#elif GTEST_OS_SYMBIAN
// Symbian OpenC has PATH_MAX in sys/syslimits.h
# include <sys/syslimits.h>
#else
# include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE
#if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX)
# define GTEST_PATH_MAX_ PATH_MAX
#elif defined(_XOPEN_PATH_MAX)
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
#else
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
#if GTEST_OS_WINDOWS
// On Windows, '\\' is the standard path separator, but many tools and the
// Windows API also accept '/' as an alternate path separator. Unless otherwise
// noted, a file path can contain either kind of path separators, or a mixture
// of them.
const char kPathSeparator = '\\';
const char kAlternatePathSeparator = '/';
const char kPathSeparatorString[] = "\\";
const char kAlternatePathSeparatorString[] = "/";
# if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory. You should not use
// the current directory in tests on Windows CE, but this at least
// provides a reasonable fallback.
const char kCurrentDirectoryString[] = "\\";
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
const DWORD kInvalidFileAttributes = 0xffffffff;
# else
const char kCurrentDirectoryString[] = ".\\";
# endif // GTEST_OS_WINDOWS_MOBILE
#else
const char kPathSeparator = '/';
const char kPathSeparatorString[] = "/";
const char kCurrentDirectoryString[] = "./";
#endif // GTEST_OS_WINDOWS
// Returns whether the given character is a valid path separator.
static bool IsPathSeparator(char c) {
#if GTEST_HAS_ALT_PATH_SEP_
return (c == kPathSeparator) || (c == kAlternatePathSeparator);
#else
return c == kPathSeparator;
#endif
}
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory, so we just return
// something reasonable.
return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
#else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE
}
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath FilePath::RemoveExtension(const char* extension) const {
const std::string dot_extension = std::string(".") + extension;
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
return FilePath(pathname_.substr(
0, pathname_.length() - dot_extension.length()));
}
return *this;
}
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FilePath::FindLastPathSeparator() const {
const char* const last_sep = strrchr(c_str(), kPathSeparator);
#if GTEST_HAS_ALT_PATH_SEP_
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
// Comparing two pointers of which only one is NULL is undefined.
if (last_alt_sep != NULL &&
(last_sep == NULL || last_alt_sep > last_sep)) {
return last_alt_sep;
}
#endif
return last_sep;
}
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveDirectoryName() const {
const char* const last_sep = FindLastPathSeparator();
return last_sep ? FilePath(last_sep + 1) : *this;
}
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveFileName() const {
const char* const last_sep = FindLastPathSeparator();
std::string dir;
if (last_sep) {
dir = std::string(c_str(), last_sep + 1 - c_str());
} else {
dir = kCurrentDirectoryString;
}
return FilePath(dir);
}
// Helper functions for naming files in a directory for xml output.
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
FilePath FilePath::MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension) {
std::string file;
if (number == 0) {
file = base_name.string() + "." + extension;
} else {
file = base_name.string() + "_" + StreamableToString(number)
+ "." + extension;
}
return ConcatPaths(directory, FilePath(file));
}
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
FilePath FilePath::ConcatPaths(const FilePath& directory,
const FilePath& relative_path) {
if (directory.IsEmpty())
return relative_path;
const FilePath dir(directory.RemoveTrailingPathSeparator());
return FilePath(dir.string() + kPathSeparator + relative_path.string());
}
// Returns true if pathname describes something findable in the file-system,
// either a file, directory, or whatever.
bool FilePath::FileOrDirectoryExists() const {
#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
return attributes != kInvalidFileAttributes;
#else
posix::StatStruct file_stat;
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
#endif // GTEST_OS_WINDOWS_MOBILE
}
// Returns true if pathname describes a directory in the file-system
// that exists.
bool FilePath::DirectoryExists() const {
bool result = false;
#if GTEST_OS_WINDOWS
// Don't strip off trailing separator if path is a root directory on
// Windows (like "C:\\").
const FilePath& path(IsRootDirectory() ? *this :
RemoveTrailingPathSeparator());
#else
const FilePath& path(*this);
#endif
#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
if ((attributes != kInvalidFileAttributes) &&
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
result = true;
}
#else
posix::StatStruct file_stat;
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE
return result;
}
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS
// TODO(wan@google.com): on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
#endif
}
// Returns true if pathname describes an absolute path.
bool FilePath::IsAbsolutePath() const {
const char* const name = pathname_.c_str();
#if GTEST_OS_WINDOWS
return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' &&
IsPathSeparator(name[2]);
#else
return IsPathSeparator(name[0]);
#endif
}
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension) {
FilePath full_pathname;
int number = 0;
do {
full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
} while (full_pathname.FileOrDirectoryExists());
return full_pathname;
}
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool FilePath::IsDirectory() const {
return !pathname_.empty() &&
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
}
// Create directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create directories
// for any reason.
bool FilePath::CreateDirectoriesRecursively() const {
if (!this->IsDirectory()) {
return false;
}
if (pathname_.length() == 0 || this->DirectoryExists()) {
return true;
}
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
return parent.CreateDirectoriesRecursively() && this->CreateFolder();
}
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool FilePath::CreateFolder() const {
#if GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
int result = CreateDirectory(unicode, NULL) ? 0 : -1;
delete [] unicode;
#elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str());
#else
int result = mkdir(pathname_.c_str(), 0777);
#endif // GTEST_OS_WINDOWS_MOBILE
if (result == -1) {
return this->DirectoryExists(); // An error is OK if the directory exists.
}
return true; // No error.
}
// If input name has a trailing separator character, remove it and return the
// name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const {
return IsDirectory()
? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this;
}
// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
if (pathname_.c_str() == NULL) {
pathname_ = "";
return;
}
const char* src = pathname_.c_str();
char* const dest = new char[pathname_.length() + 1];
char* dest_ptr = dest;
memset(dest_ptr, 0, pathname_.length() + 1);
while (*src != '\0') {
*dest_ptr = *src;
if (!IsPathSeparator(*src)) {
src++;
} else {
#if GTEST_HAS_ALT_PATH_SEP_
if (*dest_ptr == kAlternatePathSeparator) {
*dest_ptr = kPathSeparator;
}
#endif
while (IsPathSeparator(*src))
src++;
}
dest_ptr++;
}
*dest_ptr = '\0';
pathname_ = dest;
delete[] dest;
}
} // namespace internal
} // namespace testing

View File

@@ -1,373 +1,363 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Test - The Google C++ Testing Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
//
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
//
// It uses the << operator when possible, and prints the bytes in the
// object otherwise. A user can override its behavior for a class
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
// defines Foo.
#include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h>
#include <cwchar>
#include <ostream> // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace {
using ::std::ostream;
// Prints a segment of bytes in the given object.
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
size_t count, ostream* os) {
char text[5] = "";
for (size_t i = 0; i != count; i++) {
const size_t j = start + i;
if (i != 0) {
// Organizes the bytes into groups of 2 for easy parsing by
// human.
if ((j % 2) == 0)
*os << ' ';
else
*os << '-';
}
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
*os << text;
}
}
// Prints the bytes in the given value to the given ostream.
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
ostream* os) {
// Tells the user how big the object is.
*os << count << "-byte object <";
const size_t kThreshold = 132;
const size_t kChunkSize = 64;
// If the object size is bigger than kThreshold, we'll have to omit
// some details by printing only the first and the last kChunkSize
// bytes.
// TODO(wan): let the user control the threshold using a flag.
if (count < kThreshold) {
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
} else {
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
*os << " ... ";
// Rounds up to 2-byte boundary.
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
}
*os << ">";
}
} // namespace
namespace internal2 {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which
// uses the << operator and thus is easier done outside of the
// ::testing::internal namespace, which contains a << operator that
// sometimes conflicts with the one in STL.
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
ostream* os) {
PrintBytesInObjectToImpl(obj_bytes, count, os);
}
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexidecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
kAsIs,
kHexEscape,
kSpecialEscape
};
// Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
return 0x20 <= c && c <= 0x7E;
}
// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
switch (static_cast<wchar_t>(c)) {
case L'\0':
*os << "\\0";
break;
case L'\'':
*os << "\\'";
break;
case L'\\':
*os << "\\\\";
break;
case L'\a':
*os << "\\a";
break;
case L'\b':
*os << "\\b";
break;
case L'\f':
*os << "\\f";
break;
case L'\n':
*os << "\\n";
break;
case L'\r':
*os << "\\r";
break;
case L'\t':
*os << "\\t";
break;
case L'\v':
*os << "\\v";
break;
default:
if (IsPrintableAscii(c)) {
*os << static_cast<char>(c);
return kAsIs;
} else {
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
return kHexEscape;
}
}
return kSpecialEscape;
}
// Prints a wchar_t c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
switch (c) {
case L'\'':
*os << "'";
return kAsIs;
case L'"':
*os << "\\\"";
return kSpecialEscape;
default:
return PrintAsCharLiteralTo<wchar_t>(c, os);
}
}
// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsStringLiteralTo(
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
}
// Prints a wide or narrow character c and its code. '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence. The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) {
// First, print c as a literal in the most readable form we can find.
*os << ((sizeof(c) > 1) ? "L'" : "'");
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
*os << "'";
// To aid user debugging, we also print c's code in decimal, unless
// it's 0 (in which case c was printed as '\\0', making the code
// obvious).
if (c == 0)
return;
*os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexidecimal,
// unless c was already printed in the form '\x##' or the code is in
// [1, 9].
if (format == kHexEscape || (1 <= c && c <= 9)) {
// Do nothing.
} else {
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
}
*os << ")";
}
void PrintTo(unsigned char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) {
PrintCharAndCodeTo<wchar_t>(wc, os);
}
// Prints the given array of characters to the ostream. CharType must be either
// char or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) {
// Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to
// disambiguate.
*os << "\" " << kQuoteBegin;
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
}
*os << "\"";
}
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
// 'begin'. CharType must be either char or wchar_t.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) {
// The code
// const char kFoo[] = "foo";
// generates an array of 4, not 3, elements, with the last one being '\0'.
//
// Therefore when printing a char array, we don't print the last element if
// it's '\0', such that the output matches the string literal as it's
// written in the source code.
if (len > 0 && begin[len - 1] == '\0') {
PrintCharsAsStringTo(begin, len - 1, os);
return;
}
// If, however, the last element in the array is not '\0', e.g.
// const char kFoo[] = { 'f', 'o', 'o' };
// we must print the entire array. We also print a message to indicate
// that the array is not NUL-terminated.
PrintCharsAsStringTo(begin, len, os);
*os << " (no terminating NUL)";
}
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) wchar_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, strlen(s), os);
}
}
// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, std::wcslen(s), os);
}
}
#endif // wchar_t is native
// Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::std::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
// Prints a ::wstring object.
#if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_GLOBAL_WSTRING
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_STD_WSTRING
} // namespace internal
} // namespace testing
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Test - The Google C++ Testing Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
//
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
//
// It uses the << operator when possible, and prints the bytes in the
// object otherwise. A user can override its behavior for a class
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
// defines Foo.
#include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h>
#include <ostream> // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace {
using ::std::ostream;
// Prints a segment of bytes in the given object.
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
size_t count, ostream* os) {
char text[5] = "";
for (size_t i = 0; i != count; i++) {
const size_t j = start + i;
if (i != 0) {
// Organizes the bytes into groups of 2 for easy parsing by
// human.
if ((j % 2) == 0)
*os << ' ';
else
*os << '-';
}
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
*os << text;
}
}
// Prints the bytes in the given value to the given ostream.
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
ostream* os) {
// Tells the user how big the object is.
*os << count << "-byte object <";
const size_t kThreshold = 132;
const size_t kChunkSize = 64;
// If the object size is bigger than kThreshold, we'll have to omit
// some details by printing only the first and the last kChunkSize
// bytes.
// TODO(wan): let the user control the threshold using a flag.
if (count < kThreshold) {
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
} else {
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
*os << " ... ";
// Rounds up to 2-byte boundary.
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
}
*os << ">";
}
} // namespace
namespace internal2 {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which
// uses the << operator and thus is easier done outside of the
// ::testing::internal namespace, which contains a << operator that
// sometimes conflicts with the one in STL.
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
ostream* os) {
PrintBytesInObjectToImpl(obj_bytes, count, os);
}
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexidecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
kAsIs,
kHexEscape,
kSpecialEscape
};
// Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
return 0x20 <= c && c <= 0x7E;
}
// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
switch (static_cast<wchar_t>(c)) {
case L'\0':
*os << "\\0";
break;
case L'\'':
*os << "\\'";
break;
case L'\\':
*os << "\\\\";
break;
case L'\a':
*os << "\\a";
break;
case L'\b':
*os << "\\b";
break;
case L'\f':
*os << "\\f";
break;
case L'\n':
*os << "\\n";
break;
case L'\r':
*os << "\\r";
break;
case L'\t':
*os << "\\t";
break;
case L'\v':
*os << "\\v";
break;
default:
if (IsPrintableAscii(c)) {
*os << static_cast<char>(c);
return kAsIs;
} else {
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
return kHexEscape;
}
}
return kSpecialEscape;
}
// Prints a wchar_t c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
switch (c) {
case L'\'':
*os << "'";
return kAsIs;
case L'"':
*os << "\\\"";
return kSpecialEscape;
default:
return PrintAsCharLiteralTo<wchar_t>(c, os);
}
}
// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsStringLiteralTo(
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
}
// Prints a wide or narrow character c and its code. '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence. The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) {
// First, print c as a literal in the most readable form we can find.
*os << ((sizeof(c) > 1) ? "L'" : "'");
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
*os << "'";
// To aid user debugging, we also print c's code in decimal, unless
// it's 0 (in which case c was printed as '\\0', making the code
// obvious).
if (c == 0)
return;
*os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexidecimal,
// unless c was already printed in the form '\x##' or the code is in
// [1, 9].
if (format == kHexEscape || (1 <= c && c <= 9)) {
// Do nothing.
} else {
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
}
*os << ")";
}
void PrintTo(unsigned char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) {
PrintCharAndCodeTo<wchar_t>(wc, os);
}
// Prints the given array of characters to the ostream. CharType must be either
// char or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated.
template <typename CharType>
static void PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
bool is_previous_hex = false;
for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) {
// Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to
// disambiguate.
*os << "\" " << kQuoteBegin;
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
}
*os << "\"";
}
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
// 'begin'. CharType must be either char or wchar_t.
template <typename CharType>
static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) {
// The code
// const char kFoo[] = "foo";
// generates an array of 4, not 3, elements, with the last one being '\0'.
//
// Therefore when printing a char array, we don't print the last element if
// it's '\0', such that the output matches the string literal as it's
// written in the source code.
if (len > 0 && begin[len - 1] == '\0') {
PrintCharsAsStringTo(begin, len - 1, os);
return;
}
// If, however, the last element in the array is not '\0', e.g.
// const char kFoo[] = { 'f', 'o', 'o' };
// we must print the entire array. We also print a message to indicate
// that the array is not NUL-terminated.
PrintCharsAsStringTo(begin, len, os);
*os << " (no terminating NUL)";
}
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) wchar_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, strlen(s), os);
}
}
// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
if (s == NULL) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, wcslen(s), os);
}
}
#endif // wchar_t is native
// Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::std::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
// Prints a ::wstring object.
#if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_GLOBAL_WSTRING
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_STD_WSTRING
} // namespace internal
} // namespace testing

View File

@@ -1,110 +1,110 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// The Google C++ Testing Framework (Google Test)
#include "gtest/gtest-test-part.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// his code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing {
using internal::GetUnitTestImpl;
// Gets the summary of the failure message by omitting the stack trace
// in it.
std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
return stack_trace == NULL ? message :
std::string(message, stack_trace);
}
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os
<< result.file_name() << ":" << result.line_number() << ": "
<< (result.type() == TestPartResult::kSuccess ? "Success" :
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
"Non-fatal failure") << ":\n"
<< result.message() << std::endl;
}
// Appends a TestPartResult to the array.
void TestPartResultArray::Append(const TestPartResult& result) {
array_.push_back(result);
}
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
if (index < 0 || index >= size()) {
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
internal::posix::Abort();
}
return array_[index];
}
// Returns the number of TestPartResult objects in the array.
int TestPartResultArray::size() const {
return static_cast<int>(array_.size());
}
namespace internal {
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
: has_new_fatal_failure_(false),
original_reporter_(GetUnitTestImpl()->
GetTestPartResultReporterForCurrentThread()) {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
}
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
original_reporter_);
}
void HasNewFatalFailureHelper::ReportTestPartResult(
const TestPartResult& result) {
if (result.fatally_failed())
has_new_fatal_failure_ = true;
original_reporter_->ReportTestPartResult(result);
}
} // namespace internal
} // namespace testing
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// The Google C++ Testing Framework (Google Test)
#include "gtest/gtest-test-part.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// his code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing {
using internal::GetUnitTestImpl;
// Gets the summary of the failure message by omitting the stack trace
// in it.
std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
return stack_trace == NULL ? message :
std::string(message, stack_trace);
}
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os
<< result.file_name() << ":" << result.line_number() << ": "
<< (result.type() == TestPartResult::kSuccess ? "Success" :
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
"Non-fatal failure") << ":\n"
<< result.message() << std::endl;
}
// Appends a TestPartResult to the array.
void TestPartResultArray::Append(const TestPartResult& result) {
array_.push_back(result);
}
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
if (index < 0 || index >= size()) {
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
internal::posix::Abort();
}
return array_[index];
}
// Returns the number of TestPartResult objects in the array.
int TestPartResultArray::size() const {
return static_cast<int>(array_.size());
}
namespace internal {
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
: has_new_fatal_failure_(false),
original_reporter_(GetUnitTestImpl()->
GetTestPartResultReporterForCurrentThread()) {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
}
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
original_reporter_);
}
void HasNewFatalFailureHelper::ReportTestPartResult(
const TestPartResult& result) {
if (result.fatally_failed())
has_new_fatal_failure_ = true;
original_reporter_->ReportTestPartResult(result);
}
} // namespace internal
} // namespace testing

View File

@@ -1,110 +1,110 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h"
namespace testing {
namespace internal {
#if GTEST_HAS_TYPED_TEST_P
// Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters.
static const char* SkipSpaces(const char* str) {
while (IsSpace(*str))
str++;
return str;
}
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
const char* TypedTestCasePState::VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests) {
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
registered_ = true;
// Skip initial whitespace in registered_tests since some
// preprocessors prefix stringizied literals with whitespace.
registered_tests = SkipSpaces(registered_tests);
Message errors;
::std::set<std::string> tests;
for (const char* names = registered_tests; names != NULL;
names = SkipComma(names)) {
const std::string name = GetPrefixUntilComma(names);
if (tests.count(name) != 0) {
errors << "Test " << name << " is listed more than once.\n";
continue;
}
bool found = false;
for (DefinedTestIter it = defined_test_names_.begin();
it != defined_test_names_.end();
++it) {
if (name == *it) {
found = true;
break;
}
}
if (found) {
tests.insert(name);
} else {
errors << "No test named " << name
<< " can be found in this test case.\n";
}
}
for (DefinedTestIter it = defined_test_names_.begin();
it != defined_test_names_.end();
++it) {
if (tests.count(*it) == 0) {
errors << "You forgot to list test " << *it << ".\n";
}
}
const std::string& errors_str = errors.GetString();
if (errors_str != "") {
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors_str.c_str());
fflush(stderr);
posix::Abort();
}
return registered_tests;
}
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h"
namespace testing {
namespace internal {
#if GTEST_HAS_TYPED_TEST_P
// Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters.
static const char* SkipSpaces(const char* str) {
while (IsSpace(*str))
str++;
return str;
}
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
const char* TypedTestCasePState::VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests) {
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
registered_ = true;
// Skip initial whitespace in registered_tests since some
// preprocessors prefix stringizied literals with whitespace.
registered_tests = SkipSpaces(registered_tests);
Message errors;
::std::set<std::string> tests;
for (const char* names = registered_tests; names != NULL;
names = SkipComma(names)) {
const std::string name = GetPrefixUntilComma(names);
if (tests.count(name) != 0) {
errors << "Test " << name << " is listed more than once.\n";
continue;
}
bool found = false;
for (DefinedTestIter it = defined_test_names_.begin();
it != defined_test_names_.end();
++it) {
if (name == *it) {
found = true;
break;
}
}
if (found) {
tests.insert(name);
} else {
errors << "No test named " << name
<< " can be found in this test case.\n";
}
}
for (DefinedTestIter it = defined_test_names_.begin();
it != defined_test_names_.end();
++it) {
if (tests.count(*it) == 0) {
errors << "You forgot to list test " << *it << ".\n";
}
}
const std::string& errors_str = errors.GetString();
if (errors_str != "") {
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors_str.c_str());
fflush(stderr);
posix::Abort();
}
return registered_tests;
}
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing

View File

@@ -1,38 +1,38 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used cardinalities. More
// cardinalities can be defined by the user implementing the
// CardinalityInterface interface if necessary.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h>
#include <ostream> // NOLINT
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
namespace testing {
// To implement a cardinality Foo, define:
// 1. a class FooCardinality that implements the
// CardinalityInterface interface, and
// 2. a factory function that creates a Cardinality object from a
// const FooCardinality*.
//
// The two-level delegation design follows that of Matcher, providing
// consistency for extension developers. It also eases ownership
// management as Cardinality objects can now be copied like plain values.
// The implementation of a cardinality.
class CardinalityInterface {
public:
virtual ~CardinalityInterface() {}
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
virtual int ConservativeLowerBound() const { return 0; }
virtual int ConservativeUpperBound() const { return INT_MAX; }
// Returns true iff call_count calls will satisfy this cardinality.
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
// Returns true iff call_count calls will saturate this cardinality.
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
// Describes self to an ostream.
virtual void DescribeTo(::std::ostream* os) const = 0;
};
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
// object that specifies how many times a mock function is expected to
// be called. The implementation of Cardinality is just a linked_ptr
// to const CardinalityInterface, so copying is fairly cheap.
// Don't inherit from Cardinality!
class GTEST_API_ Cardinality {
public:
// Constructs a null cardinality. Needed for storing Cardinality
// objects in STL containers.
Cardinality() {}
// Constructs a Cardinality from its implementation.
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
// Returns true iff call_count calls will satisfy this cardinality.
bool IsSatisfiedByCallCount(int call_count) const {
return impl_->IsSatisfiedByCallCount(call_count);
}
// Returns true iff call_count calls will saturate this cardinality.
bool IsSaturatedByCallCount(int call_count) const {
return impl_->IsSaturatedByCallCount(call_count);
}
// Returns true iff call_count calls will over-saturate this
// cardinality, i.e. exceed the maximum number of allowed calls.
bool IsOverSaturatedByCallCount(int call_count) const {
return impl_->IsSaturatedByCallCount(call_count) &&
!impl_->IsSatisfiedByCallCount(call_count);
}
// Describes self to an ostream
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
// Describes the given actual call count to an ostream.
static void DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os);
private:
internal::linked_ptr<const CardinalityInterface> impl_;
};
// Creates a cardinality that allows at least n calls.
GTEST_API_ Cardinality AtLeast(int n);
// Creates a cardinality that allows at most n calls.
GTEST_API_ Cardinality AtMost(int n);
// Creates a cardinality that allows any number of calls.
GTEST_API_ Cardinality AnyNumber();
// Creates a cardinality that allows between min and max calls.
GTEST_API_ Cardinality Between(int min, int max);
// Creates a cardinality that allows exactly n calls.
GTEST_API_ Cardinality Exactly(int n);
// Creates a cardinality from its implementation.
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
return Cardinality(c);
}
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,821 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$}} This meta comment fixes auto-indentation in editors.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
// function or method with the unpacked values, where F is a function
// type that takes N arguments.
template <typename Result, typename ArgumentTuple>
class InvokeHelper;
$range i 0..n
$for i [[
$range j 1..i
$var types = [[$for j [[, typename A$j]]]]
$var as = [[$for j, [[A$j]]]]
$var args = [[$if i==0 [[]] $else [[ args]]]]
$var import = [[$if i==0 [[]] $else [[
using ::std::tr1::get;
]]]]
$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
template <typename R$types>
class InvokeHelper<R, ::std::tr1::tuple<$as> > {
public:
template <typename Function>
static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
$import return function($gets);
}
template <class Class, typename MethodPtr>
static R InvokeMethod(Class* obj_ptr,
MethodPtr method_ptr,
const ::std::tr1::tuple<$as>&$args) {
$import return (obj_ptr->*method_ptr)($gets);
}
};
]]
// CallableHelper has static methods for invoking "callables",
// i.e. function pointers and functors. It uses overloading to
// provide a uniform interface for invoking different kinds of
// callables. In particular, you can use:
//
// CallableHelper<R>::Call(callable, a1, a2, ..., an)
//
// to invoke an n-ary callable, where R is its return type. If an
// argument, say a2, needs to be passed by reference, you should write
// ByRef(a2) instead of a2 in the above expression.
template <typename R>
class CallableHelper {
public:
// Calls a nullary callable.
template <typename Function>
static R Call(Function function) { return function(); }
// Calls a unary callable.
// We deliberately pass a1 by value instead of const reference here
// in case it is a C-string literal. If we had declared the
// parameter as 'const A1& a1' and write Call(function, "Hi"), the
// compiler would've thought A1 is 'char[3]', which causes trouble
// when you need to copy a value of type A1. By declaring the
// parameter as 'A1 a1', the compiler will correctly infer that A1
// is 'const char*' when it sees Call(function, "Hi").
//
// Since this function is defined inline, the compiler can get rid
// of the copying of the arguments. Therefore the performance won't
// be hurt.
template <typename Function, typename A1>
static R Call(Function function, A1 a1) { return function(a1); }
$range i 2..n
$for i
[[
$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
// Calls a $arity callable.
$range j 1..i
$var typename_As = [[$for j, [[typename A$j]]]]
$var Aas = [[$for j, [[A$j a$j]]]]
$var as = [[$for j, [[a$j]]]]
$var typename_Ts = [[$for j, [[typename T$j]]]]
$var Ts = [[$for j, [[T$j]]]]
template <typename Function, $typename_As>
static R Call(Function function, $Aas) {
return function($as);
}
]]
}; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's
// subject to change without notice - DO NOT USE IN USER CODE!
#define GMOCK_FIELD_(Tuple, N) \
typename ::std::tr1::tuple_element<N, Tuple>::type
$range i 1..n
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
// type of an n-ary function whose i-th (1-based) argument type is the
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
// type, and whose return type is Result. For example,
// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
// is int(bool, long).
//
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
// For example,
// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
// ::std::tr1::make_tuple(true, 'a', 2.5))
// returns ::std::tr1::tuple (2.5, true).
//
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
// in the range [0, $n]. Duplicates are allowed and they don't have
// to be in an ascending or descending order.
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
class SelectArgs {
public:
typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
typedef typename Function<type>::ArgumentTuple SelectedArgs;
static SelectedArgs Select(const ArgumentTuple& args) {
using ::std::tr1::get;
return SelectedArgs($for i, [[get<k$i>(args)]]);
}
};
$for i [[
$range j 1..n
$range j1 1..i-1
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
class SelectArgs<Result, ArgumentTuple,
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
public:
typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
typedef typename Function<type>::ArgumentTuple SelectedArgs;
static SelectedArgs Select(const ArgumentTuple& [[]]
$if i == 1 [[/* args */]] $else [[args]]) {
using ::std::tr1::get;
return SelectedArgs($for j1, [[get<k$j1>(args)]]);
}
};
]]
#undef GMOCK_FIELD_
$var ks = [[$for i, [[k$i]]]]
// Implements the WithArgs action.
template <typename InnerAction, $for i, [[int k$i = -1]]>
class WithArgsAction {
public:
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
template <typename F>
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
private:
template <typename F>
class Impl : public ActionInterface<F> {
public:
typedef typename Function<F>::Result Result;
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
explicit Impl(const InnerAction& action) : action_(action) {}
virtual Result Perform(const ArgumentTuple& args) {
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
}
private:
typedef typename SelectArgs<Result, ArgumentTuple,
$ks>::type InnerFunctionType;
Action<InnerFunctionType> action_;
};
const InnerAction action_;
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
};
// A macro from the ACTION* family (defined later in this file)
// defines an action that can be used in a mock function. Typically,
// these actions only care about a subset of the arguments of the mock
// function. For example, if such an action only uses the second
// argument, it can be used in any mock function that takes >= 2
// arguments where the type of the second argument is compatible.
//
// Therefore, the action implementation must be prepared to take more
// arguments than it needs. The ExcessiveArg type is used to
// represent those excessive arguments. In order to keep the compiler
// error messages tractable, we define it in the testing namespace
// instead of testing::internal. However, this is an INTERNAL TYPE
// and subject to change without notice, so a user MUST NOT USE THIS
// TYPE DIRECTLY.
struct ExcessiveArg {};
// A helper class needed for implementing the ACTION* macros.
template <typename Result, class Impl>
class ActionHelper {
public:
$range i 0..n
$for i
[[
$var template = [[$if i==0 [[]] $else [[
$range j 0..i-1
template <$for j, [[typename A$j]]>
]]]]
$range j 0..i-1
$var As = [[$for j, [[A$j]]]]
$var as = [[$for j, [[get<$j>(args)]]]]
$range k 1..n-i
$var eas = [[$for k, [[ExcessiveArg()]]]]
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
$template
static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
using ::std::tr1::get;
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
}
]]
};
} // namespace internal
// Various overloads for Invoke().
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
// the selected arguments of the mock function to an_action and
// performs it. It serves as an adaptor between actions with
// different argument lists. C++ doesn't support default arguments for
// function templates, so we have to overload it.
$range i 1..n
$for i [[
$range j 1..i
template <$for j [[int k$j, ]]typename InnerAction>
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
WithArgs(const InnerAction& action) {
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
}
]]
// Creates an action that does actions a1, a2, ..., sequentially in
// each invocation.
$range i 2..n
$for i [[
$range j 2..i
$var types = [[$for j, [[typename Action$j]]]]
$var Aas = [[$for j [[, Action$j a$j]]]]
template <typename Action1, $types>
$range k 1..i-1
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
DoAll(Action1 a1$Aas) {
$if i==2 [[
return internal::DoBothAction<Action1, Action2>(a1, a2);
]] $else [[
$range j2 2..i
return DoAll(a1, DoAll($for j2, [[a$j2]]));
]]
}
]]
} // namespace testing
// The ACTION* family of macros can be used in a namespace scope to
// define custom actions easily. The syntax:
//
// ACTION(name) { statements; }
//
// will define an action with the given name that executes the
// statements. The value returned by the statements will be used as
// the return value of the action. Inside the statements, you can
// refer to the K-th (0-based) argument of the mock function by
// 'argK', and refer to its type by 'argK_type'. For example:
//
// ACTION(IncrementArg1) {
// arg1_type temp = arg1;
// return ++(*temp);
// }
//
// allows you to write
//
// ...WillOnce(IncrementArg1());
//
// You can also refer to the entire argument tuple and its type by
// 'args' and 'args_type', and refer to the mock function type and its
// return type by 'function_type' and 'return_type'.
//
// Note that you don't need to specify the types of the mock function
// arguments. However rest assured that your code is still type-safe:
// you'll get a compiler error if *arg1 doesn't support the ++
// operator, or if the type of ++(*arg1) isn't compatible with the
// mock function's return type, for example.
//
// Sometimes you'll want to parameterize the action. For that you can use
// another macro:
//
// ACTION_P(name, param_name) { statements; }
//
// For example:
//
// ACTION_P(Add, n) { return arg0 + n; }
//
// will allow you to write:
//
// ...WillOnce(Add(5));
//
// Note that you don't need to provide the type of the parameter
// either. If you need to reference the type of a parameter named
// 'foo', you can write 'foo_type'. For example, in the body of
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
// of 'n'.
//
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
// multi-parameter actions.
//
// For the purpose of typing, you can view
//
// ACTION_Pk(Foo, p1, ..., pk) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
//
// In particular, you can provide the template type arguments
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
// although usually you can rely on the compiler to infer the types
// for you automatically. You can assign the result of expression
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
// pk_type>. This can be useful when composing actions.
//
// You can also overload actions with different numbers of parameters:
//
// ACTION_P(Plus, a) { ... }
// ACTION_P2(Plus, a, b) { ... }
//
// While it's tempting to always use the ACTION* macros when defining
// a new action, you should also consider implementing ActionInterface
// or using MakePolymorphicAction() instead, especially if you need to
// use the action a lot. While these approaches require more work,
// they give you more control on the types of the mock function
// arguments and the action parameters, which in general leads to
// better compiler error messages that pay off in the long run. They
// also allow overloading actions based on parameter types (as opposed
// to just based on the number of parameters).
//
// CAVEAT:
//
// ACTION*() can only be used in a namespace scope. The reason is
// that C++ doesn't yet allow function-local types to be used to
// instantiate templates. The up-coming C++0x standard will fix this.
// Once that's done, we'll consider supporting using ACTION*() inside
// a function.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION'
// on http://code.google.com/p/googlemock/wiki/CookBook.
$range i 0..n
$range k 0..n-1
// An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_
$for k [[, \
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
// Sometimes you want to give an action explicit template parameters
// that cannot be inferred from its value parameters. ACTION() and
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
// and can be viewed as an extension to ACTION() and ACTION_P*().
//
// The syntax:
//
// ACTION_TEMPLATE(ActionName,
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
//
// defines an action template that takes m explicit template
// parameters and n value parameters. name_i is the name of the i-th
// template parameter, and kind_i specifies whether it's a typename,
// an integral constant, or a template. p_i is the name of the i-th
// value parameter.
//
// Example:
//
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
// // function to type T and copies it to *output.
// ACTION_TEMPLATE(DuplicateArg,
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
// AND_1_VALUE_PARAMS(output)) {
// *output = T(std::tr1::get<k>(args));
// }
// ...
// int n;
// EXPECT_CALL(mock, Foo(_, _))
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
//
// To create an instance of an action template, write:
//
// ActionName<t1, ..., t_m>(v1, ..., v_n)
//
// where the ts are the template arguments and the vs are the value
// arguments. The value argument types are inferred by the compiler.
// If you want to explicitly specify the value argument types, you can
// provide additional template arguments:
//
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
//
// where u_i is the desired type of v_i.
//
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
// number of value parameters, but not on the number of template
// parameters. Without the restriction, the meaning of the following
// is unclear:
//
// OverloadedAction<int, bool>(x);
//
// Are we using a single-template-parameter action where 'bool' refers
// to the type of x, or are we using a two-template-parameter action
// where the compiler is asked to infer the type of x?
//
// Implementation notes:
//
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
// implementing ACTION_TEMPLATE. The main trick we use is to create
// new macro invocations when expanding a macro. For example, we have
//
// #define ACTION_TEMPLATE(name, template_params, value_params)
// ... GMOCK_INTERNAL_DECL_##template_params ...
//
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
// to expand to
//
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
//
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
// preprocessor will continue to expand it to
//
// ... typename T ...
//
// This technique conforms to the C++ standard and is portable. It
// allows us to implement action templates using O(N) code, where N is
// the maximum number of template/value parameters supported. Without
// using it, we'd have to devote O(N^2) amount of code to implement all
// combinations of m and n.
// Declares the template parameters.
$range j 1..n
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
]]
// Lists the template parameters.
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
]]
// Declares the types of value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
]]
// Initializes the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
]]
// Declares the fields for storing the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
]]
// Lists the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
]]
// Lists the value parameter types.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
]]
// Declares the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
$for j, [[p$j##_type p$j]]
]]
// The suffix of the class template implementing the action template.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
$if i==1 [[P]] $elif i>=2 [[P$i]]
]]
// The name of the class template implementing the action template.
#define GMOCK_ACTION_CLASS_(name, value_params)\
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
$range k 0..n-1
#define ACTION_TEMPLATE(name, template_params, value_params)\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
class GMOCK_ACTION_CLASS_(name, value_params) {\
public:\
GMOCK_ACTION_CLASS_(name, value_params)\
GMOCK_INTERNAL_INIT_##value_params {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <$for k, [[typename arg$k[[]]_type]]>\
return_type gmock_PerformImpl(const args_type& args[[]]
$for k [[, arg$k[[]]_type arg$k]]) const;\
GMOCK_INTERNAL_DEFN_##value_params\
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(\
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
}\
GMOCK_INTERNAL_DEFN_##value_params\
private:\
GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
};\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
inline GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
GMOCK_INTERNAL_DECL_##value_params) {\
return GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
GMOCK_INTERNAL_LIST_##value_params);\
}\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
$for i
[[
$var template = [[$if i==0 [[]] $else [[
$range j 0..i-1
template <$for j, [[typename p$j##_type]]>\
]]]]
$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
$else [[P$i]]]]]]
$range j 0..i-1
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
$var param_field_decls = [[$for j
[[
p$j##_type p$j;\
]]]]
$var param_field_decls2 = [[$for j
[[
p$j##_type p$j;\
]]]]
$var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
$else [[ACTION_P$i]]]]
#define $macro_name(name$for j [[, p$j]])\$template
class $class_name {\
public:\
$class_name($ctor_param_list)$inits {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <$typename_arg_types>\
return_type gmock_PerformImpl(const args_type& args, [[]]
$arg_types_and_names) const;\$param_field_decls
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>($params));\
}\$param_field_decls2
private:\
GTEST_DISALLOW_ASSIGN_($class_name);\
};\$template
inline $class_name$param_types name($param_types_and_names) {\
return $class_name$param_types($params);\
}\$template
template <typename F>\
template <$typename_arg_types>\
typename ::testing::internal::Function<F>::Result\
$class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
]]
$$ } // This meta comment fixes auto-indentation in Emacs. It won't
$$ // show up in the generated code.
namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
// Various overloads for InvokeArgument<N>().
//
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
// (0-based) argument, which must be a k-ary callable, of the mock
// function, with arguments a1, a2, ..., a_k.
//
// Notes:
//
// 1. The arguments are passed by value by default. If you need to
// pass an argument by reference, wrap it inside ByRef(). For
// example,
//
// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
//
// passes 5 and string("Hello") by value, and passes foo by
// reference.
//
// 2. If the callable takes an argument by reference but ByRef() is
// not used, it will receive the reference to a copy of the value,
// instead of the original value. For example, when the 0-th
// argument of the mock function takes a const string&, the action
//
// InvokeArgument<0>(string("Hello"))
//
// makes a copy of the temporary string("Hello") object and passes a
// reference of the copy, instead of the original temporary object,
// to the callable. This makes it easy for a user to define an
// InvokeArgument action from temporary values and have it performed
// later.
$range i 0..n
$for i [[
$range j 0..i-1
ACTION_TEMPLATE(InvokeArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
return internal::CallableHelper<return_type>::Call(
::std::tr1::get<k>(args)$for j [[, p$j]]);
}
]]
// Various overloads for ReturnNew<T>().
//
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
// instance of type T, constructed on the heap with constructor arguments
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
$range i 0..n
$for i [[
$range j 0..i-1
$var ps = [[$for j, [[p$j]]]]
ACTION_TEMPLATE(ReturnNew,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_$i[[]]_VALUE_PARAMS($ps)) {
return new T($ps);
}
]]
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_

View File

@@ -0,0 +1,991 @@
// This file was GENERATED by command:
// pump.py gmock-generated-function-mockers.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements function mockers of various arities.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
template <typename F>
class FunctionMockerBase;
// Note: class FunctionMocker really belongs to the ::testing
// namespace. However if we define it in ::testing, MSVC will
// complain when classes in ::testing::internal declare it as a
// friend class template. To workaround this compiler bug, we define
// FunctionMocker in ::testing::internal and import it into ::testing.
template <typename F>
class FunctionMocker;
template <typename R>
class FunctionMocker<R()> : public
internal::FunctionMockerBase<R()> {
public:
typedef R F();
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With() {
return this->current_spec();
}
R Invoke() {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple());
}
};
template <typename R, typename A1>
class FunctionMocker<R(A1)> : public
internal::FunctionMockerBase<R(A1)> {
public:
typedef R F(A1);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
return this->current_spec();
}
R Invoke(A1 a1) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1));
}
};
template <typename R, typename A1, typename A2>
class FunctionMocker<R(A1, A2)> : public
internal::FunctionMockerBase<R(A1, A2)> {
public:
typedef R F(A1, A2);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2));
}
};
template <typename R, typename A1, typename A2, typename A3>
class FunctionMocker<R(A1, A2, A3)> : public
internal::FunctionMockerBase<R(A1, A2, A3)> {
public:
typedef R F(A1, A2, A3);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4>
class FunctionMocker<R(A1, A2, A3, A4)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
public:
typedef R F(A1, A2, A3, A4);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5>
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
public:
typedef R F(A1, A2, A3, A4, A5);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
m5));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
public:
typedef R F(A1, A2, A3, A4, A5, A6);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
const Matcher<A6>& m6) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
m6));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7>
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
public:
typedef R F(A1, A2, A3, A4, A5, A6, A7);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
const Matcher<A6>& m6, const Matcher<A7>& m7) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
m6, m7));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
public:
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
m6, m7, m8));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9>
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
public:
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
const Matcher<A9>& m9) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
m6, m7, m8, m9));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9,
typename A10>
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
public:
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
const Matcher<A9>& m9, const Matcher<A10>& m10) {
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
m6, m7, m8, m9, m10));
return this->current_spec();
}
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
A10 a10) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9,
a10));
}
};
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the FunctionMocker class template
// is meant to be defined in the ::testing namespace. The following
// line is just a trick for working around a bug in MSVC 8.0, which
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 0), \
this_method_does_not_take_0_arguments); \
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method() constness { \
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(0, constness, Method).With(); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 1), \
this_method_does_not_take_1_argument); \
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 2), \
this_method_does_not_take_2_arguments); \
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 3), \
this_method_does_not_take_3_arguments); \
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 4), \
this_method_does_not_take_4_arguments); \
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 5), \
this_method_does_not_take_5_arguments); \
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 6), \
this_method_does_not_take_6_arguments); \
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 7), \
this_method_does_not_take_7_arguments); \
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 8), \
this_method_does_not_take_8_arguments); \
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 9), \
this_method_does_not_take_9_arguments); \
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 10), \
this_method_does_not_take_10_arguments); \
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
GMOCK_MATCHER_(tn, 10, \
__VA_ARGS__) gmock_a10) constness { \
GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
Method)
#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T(m, ...) \
GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T(m, ...) \
GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T(m, ...) \
GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T(m, ...) \
GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T(m, ...) \
GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T(m, ...) \
GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T(m, ...) \
GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T(m, ...) \
GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T(m, ...) \
GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T(m, ...) \
GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T(m, ...) \
GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
// A MockFunction<F> class has one mock method whose type is F. It is
// useful when you just want your test code to emit some messages and
// have Google Mock verify the right messages are sent (and perhaps at
// the right times). For example, if you are exercising code:
//
// Foo(1);
// Foo(2);
// Foo(3);
//
// and want to verify that Foo(1) and Foo(3) both invoke
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
//
// TEST(FooTest, InvokesBarCorrectly) {
// MyMock mock;
// MockFunction<void(string check_point_name)> check;
// {
// InSequence s;
//
// EXPECT_CALL(mock, Bar("a"));
// EXPECT_CALL(check, Call("1"));
// EXPECT_CALL(check, Call("2"));
// EXPECT_CALL(mock, Bar("a"));
// }
// Foo(1);
// check.Call("1");
// Foo(2);
// check.Call("2");
// Foo(3);
// }
//
// The expectation spec says that the first Bar("a") must happen
// before check point "1", the second Bar("a") must happen after check
// point "2", and nothing should happen between the two check
// points. The explicit check points make it easy to tell which
// Bar("a") is called by which call to Foo().
template <typename F>
class MockFunction;
template <typename R>
class MockFunction<R()> {
public:
MockFunction() {}
MOCK_METHOD0_T(Call, R());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0>
class MockFunction<R(A0)> {
public:
MockFunction() {}
MOCK_METHOD1_T(Call, R(A0));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1>
class MockFunction<R(A0, A1)> {
public:
MockFunction() {}
MOCK_METHOD2_T(Call, R(A0, A1));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2>
class MockFunction<R(A0, A1, A2)> {
public:
MockFunction() {}
MOCK_METHOD3_T(Call, R(A0, A1, A2));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3>
class MockFunction<R(A0, A1, A2, A3)> {
public:
MockFunction() {}
MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4>
class MockFunction<R(A0, A1, A2, A3, A4)> {
public:
MockFunction() {}
MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4, typename A5>
class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
public:
MockFunction() {}
MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6>
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
public:
MockFunction() {}
MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6, typename A7>
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
public:
MockFunction() {}
MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6, typename A7, typename A8>
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
public:
MockFunction() {}
MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
template <typename R, typename A0, typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6, typename A7, typename A8,
typename A9>
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
public:
MockFunction() {}
MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

View File

@@ -0,0 +1,265 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-function-mockers.h.
$$
$var n = 10 $$ The maximum arity we support.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements function mockers of various arities.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
template <typename F>
class FunctionMockerBase;
// Note: class FunctionMocker really belongs to the ::testing
// namespace. However if we define it in ::testing, MSVC will
// complain when classes in ::testing::internal declare it as a
// friend class template. To workaround this compiler bug, we define
// FunctionMocker in ::testing::internal and import it into ::testing.
template <typename F>
class FunctionMocker;
$range i 0..n
$for i [[
$range j 1..i
$var typename_As = [[$for j [[, typename A$j]]]]
$var As = [[$for j, [[A$j]]]]
$var as = [[$for j, [[a$j]]]]
$var Aas = [[$for j, [[A$j a$j]]]]
$var ms = [[$for j, [[m$j]]]]
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
template <typename R$typename_As>
class FunctionMocker<R($As)> : public
internal::FunctionMockerBase<R($As)> {
public:
typedef R F($As);
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
MockSpec<F>& With($matchers) {
$if i >= 1 [[
this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
]]
return this->current_spec();
}
R Invoke($Aas) {
// Even though gcc and MSVC don't enforce it, 'this->' is required
// by the C++ standard [14.6.4] here, as the base class type is
// dependent on the template argument (and thus shouldn't be
// looked into when resolving InvokeWith).
return this->InvokeWith(ArgumentTuple($as));
}
};
]]
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the FunctionMocker class template
// is meant to be defined in the ::testing namespace. The following
// line is just a trick for working around a bug in MSVC 8.0, which
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
$for i [[
$range j 1..i
$var arg_as = [[$for j, \
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var as = [[$for j, [[gmock_a$j]]]]
$var matcher_as = [[$for j, \
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
$arg_as) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
} \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method($matcher_as) constness { \
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_($i, constness, Method).With($as); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
]]
$for i [[
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
]]
// A MockFunction<F> class has one mock method whose type is F. It is
// useful when you just want your test code to emit some messages and
// have Google Mock verify the right messages are sent (and perhaps at
// the right times). For example, if you are exercising code:
//
// Foo(1);
// Foo(2);
// Foo(3);
//
// and want to verify that Foo(1) and Foo(3) both invoke
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
//
// TEST(FooTest, InvokesBarCorrectly) {
// MyMock mock;
// MockFunction<void(string check_point_name)> check;
// {
// InSequence s;
//
// EXPECT_CALL(mock, Bar("a"));
// EXPECT_CALL(check, Call("1"));
// EXPECT_CALL(check, Call("2"));
// EXPECT_CALL(mock, Bar("a"));
// }
// Foo(1);
// check.Call("1");
// Foo(2);
// check.Call("2");
// Foo(3);
// }
//
// The expectation spec says that the first Bar("a") must happen
// before check point "1", the second Bar("a") must happen after check
// point "2", and nothing should happen between the two check
// points. The explicit check points make it easy to tell which
// Bar("a") is called by which call to Foo().
template <typename F>
class MockFunction;
$for i [[
$range j 0..i-1
template <typename R$for j [[, typename A$j]]>
class MockFunction<R($for j, [[A$j]])> {
public:
MockFunction() {}
MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
};
]]
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,674 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$ }} This line fixes auto-indentation of the following code in Emacs.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic matchers.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include "gmock/gmock-matchers.h"
namespace testing {
namespace internal {
$range i 0..n-1
// The type of the i-th (0-based) field of Tuple.
#define GMOCK_FIELD_TYPE_(Tuple, i) \
typename ::std::tr1::tuple_element<i, Tuple>::type
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
// tuple of type Tuple. It has two members:
//
// type: a tuple type whose i-th field is the ki-th field of Tuple.
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
//
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
//
// type is tuple<int, bool>, and
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
template <class Tuple$for i [[, int k$i = -1]]>
class TupleFields;
// This generic version is used when there are $n selectors.
template <class Tuple$for i [[, int k$i]]>
class TupleFields {
public:
typedef ::std::tr1::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type($for i, [[get<k$i>(t)]]);
}
};
// The following specialization is used for 0 ~ $(n-1) selectors.
$for i [[
$$ }}}
$range j 0..i-1
$range k 0..n-1
template <class Tuple$for j [[, int k$j]]>
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
public:
typedef ::std::tr1::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
using ::std::tr1::get;
return type($for j, [[get<k$j>(t)]]);
}
};
]]
#undef GMOCK_FIELD_TYPE_
// Implements the Args() matcher.
$var ks = [[$for i, [[k$i]]]]
template <class ArgsTuple$for i [[, int k$i = -1]]>
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
public:
// ArgsTuple may have top-level const or reference modifiers.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
template <typename InnerMatcher>
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
virtual bool MatchAndExplain(ArgsTuple args,
MatchResultListener* listener) const {
const SelectedArgs& selected_args = GetSelectedArgs(args);
if (!listener->IsInterested())
return inner_matcher_.Matches(selected_args);
PrintIndices(listener->stream());
*listener << "are " << PrintToString(selected_args);
StringMatchResultListener inner_listener;
const bool match = inner_matcher_.MatchAndExplain(selected_args,
&inner_listener);
PrintIfNotEmpty(inner_listener.str(), listener->stream());
return match;
}
virtual void DescribeTo(::std::ostream* os) const {
*os << "are a tuple ";
PrintIndices(os);
inner_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "are a tuple ";
PrintIndices(os);
inner_matcher_.DescribeNegationTo(os);
}
private:
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
}
// Prints the indices of the selected fields.
static void PrintIndices(::std::ostream* os) {
*os << "whose fields (";
const int indices[$n] = { $ks };
for (int i = 0; i < $n; i++) {
if (indices[i] < 0)
break;
if (i >= 1)
*os << ", ";
*os << "#" << indices[i];
}
*os << ") ";
}
const MonomorphicInnerMatcher inner_matcher_;
GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
};
template <class InnerMatcher$for i [[, int k$i = -1]]>
class ArgsMatcher {
public:
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
: inner_matcher_(inner_matcher) {}
template <typename ArgsTuple>
operator Matcher<ArgsTuple>() const {
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
}
private:
const InnerMatcher inner_matcher_;
GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
};
// A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AllOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AllOfResult$i {
typedef BothOfMatcher<
typename AllOfResult$m<$for k, [[M$k]]>::type,
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AnyOfResult$i {
typedef EitherOfMatcher<
typename AnyOfResult$m<$for k, [[M$k]]>::type,
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
$range i 0..n
$for i [[
$range j 1..i
template <$for j [[int k$j, ]]typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
}
]]
// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
// n elements, where the i-th element in the container must
// match the i-th argument in the list. Each argument of
// ElementsAre() can be either a value or a matcher. We support up to
// $n arguments.
//
// The use of DecayArray in the implementation allows ElementsAre()
// to accept string literals, whose type is const char[N], but we
// want to treat them as const char*.
//
// NOTE: Since ElementsAre() cares about the order of the elements, it
// must not be used with containers whose elements's order is
// undefined (e.g. hash_map).
$range i 0..n
$for i [[
$range j 1..i
$if i>0 [[
template <$for j, [[typename T$j]]>
]]
inline internal::ElementsAreMatcher<
std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
ElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
}
]]
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
// that matches n elements in any order. We support up to n=$n arguments.
$range i 0..n
$for i [[
$range j 1..i
$if i>0 [[
template <$for j, [[typename T$j]]>
]]
inline internal::UnorderedElementsAreMatcher<
std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
}
]]
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
$range i 2..n
$for i [[
$range j 1..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <$for j, [[typename M$j]]>
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
AllOf($for j, [[M$j m$j]]) {
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
}
]]
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
$range i 2..n
$for i [[
$range j 1..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <$for j, [[typename M$j]]>
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
AnyOf($for j, [[M$j m$j]]) {
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
}
]]
} // namespace testing
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
$$ // show up in the generated code.
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
// Basic Usage
// ===========
//
// The syntax
//
// MATCHER(name, description_string) { statements; }
//
// defines a matcher with the given name that executes the statements,
// which must return a bool to indicate if the match succeeds. Inside
// the statements, you can refer to the value being matched by 'arg',
// and refer to its type by 'arg_type'.
//
// The description string documents what the matcher does, and is used
// to generate the failure message when the match fails. Since a
// MATCHER() is usually defined in a header file shared by multiple
// C++ source files, we require the description to be a C-string
// literal to avoid possible side effects. It can be empty, in which
// case we'll use the sequence of words in the matcher name as the
// description.
//
// For example:
//
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
//
// allows you to write
//
// // Expects mock_foo.Bar(n) to be called where n is even.
// EXPECT_CALL(mock_foo, Bar(IsEven()));
//
// or,
//
// // Verifies that the value of some_expression is even.
// EXPECT_THAT(some_expression, IsEven());
//
// If the above assertion fails, it will print something like:
//
// Value of: some_expression
// Expected: is even
// Actual: 7
//
// where the description "is even" is automatically calculated from the
// matcher name IsEven.
//
// Argument Type
// =============
//
// Note that the type of the value being matched (arg_type) is
// determined by the context in which you use the matcher and is
// supplied to you by the compiler, so you don't need to worry about
// declaring it (nor can you). This allows the matcher to be
// polymorphic. For example, IsEven() can be used to match any type
// where the value of "(arg % 2) == 0" can be implicitly converted to
// a bool. In the "Bar(IsEven())" example above, if method Bar()
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
// 'arg_type' will be unsigned long; and so on.
//
// Parameterizing Matchers
// =======================
//
// Sometimes you'll want to parameterize the matcher. For that you
// can use another macro:
//
// MATCHER_P(name, param_name, description_string) { statements; }
//
// For example:
//
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
//
// will allow you to write:
//
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
//
// which may lead to this message (assuming n is 10):
//
// Value of: Blah("a")
// Expected: has absolute value 10
// Actual: -9
//
// Note that both the matcher description and its parameter are
// printed, making the message human-friendly.
//
// In the matcher definition body, you can write 'foo_type' to
// reference the type of a parameter named 'foo'. For example, in the
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
// 'value_type' to refer to the type of 'value'.
//
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
// support multi-parameter matchers.
//
// Describing Parameterized Matchers
// =================================
//
// The last argument to MATCHER*() is a string-typed expression. The
// expression can reference all of the matcher's parameters and a
// special bool-typed variable named 'negation'. When 'negation' is
// false, the expression should evaluate to the matcher's description;
// otherwise it should evaluate to the description of the negation of
// the matcher. For example,
//
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
// string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
// ...
// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
// parameter values printed as a tuple. For example,
//
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
// ...
// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
//
// For the purpose of typing, you can view
//
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooMatcherPk<p1_type, ..., pk_type>
// Foo(p1_type p1, ..., pk_type pk) { ... }
//
// When you write Foo(v1, ..., vk), the compiler infers the types of
// the parameters v1, ..., and vk for you. If you are not happy with
// the result of the type inference, you can specify the types by
// explicitly instantiating the template, as in Foo<long, bool>(5,
// false). As said earlier, you don't get to (or need to) specify
// 'arg_type' as that's determined by the context in which the matcher
// is used. You can assign the result of expression Foo(p1, ..., pk)
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
// can be useful when composing matchers.
//
// While you can instantiate a matcher template with reference types,
// passing the parameters by pointer usually makes your code more
// readable. If, however, you still want to pass a parameter by
// reference, be aware that in the failure message generated by the
// matcher you will see the value of the referenced object but not its
// address.
//
// Explaining Match Results
// ========================
//
// Sometimes the matcher description alone isn't enough to explain why
// the match has failed or succeeded. For example, when expecting a
// long string, it can be very helpful to also print the diff between
// the expected string and the actual one. To achieve that, you can
// optionally stream additional information to a special variable
// named result_listener, whose type is a pointer to class
// MatchResultListener:
//
// MATCHER_P(EqualsLongString, str, "") {
// if (arg == str) return true;
//
// *result_listener << "the difference: "
/// << DiffStrings(str, arg);
// return false;
// }
//
// Overloading Matchers
// ====================
//
// You can overload matchers with different numbers of parameters:
//
// MATCHER_P(Blah, a, description_string1) { ... }
// MATCHER_P2(Blah, a, b, description_string2) { ... }
//
// Caveats
// =======
//
// When defining a new matcher, you should also consider implementing
// MatcherInterface or using MakePolymorphicMatcher(). These
// approaches require more work than the MATCHER* macros, but also
// give you more control on the types of the value being matched and
// the matcher parameters, which may leads to better compiler error
// messages when the matcher is used wrong. They also allow
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
// MATCHER*() can only be used in a namespace scope. The reason is
// that C++ doesn't yet allow function-local types to be used to
// instantiate templates. The up-coming C++0x standard will fix this.
// Once that's done, we'll consider supporting using MATCHER*() inside
// a function.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
// on http://code.google.com/p/googlemock/wiki/CookBook.
$range i 0..n
$for i
[[
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
$else [[MATCHER_P$i]]]]
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
$else [[P$i]]]]]]
$range j 0..i-1
$var template = [[$if i==0 [[]] $else [[
template <$for j, [[typename p$j##_type]]>\
]]]]
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
$var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var param_field_decls = [[$for j
[[
p$j##_type p$j;\
]]]]
$var param_field_decls2 = [[$for j
[[
p$j##_type p$j;\
]]]]
#define $macro_name(name$for j [[, p$j]], description)\$template
class $class_name {\
public:\
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
public:\
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
$impl_inits {}\
virtual bool MatchAndExplain(\
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\$param_field_decls
private:\
::testing::internal::string FormatDescription(bool negation) const {\
const ::testing::internal::string gmock_description = (description);\
if (!gmock_description.empty())\
return gmock_description;\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>($params));\
}\
$class_name($ctor_param_list)$inits {\
}\$param_field_decls2
private:\
GTEST_DISALLOW_ASSIGN_($class_name);\
};\$template
inline $class_name$param_types name($param_types_and_names) {\
return $class_name$param_types($params);\
}\$template
template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
arg_type arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
]]
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_

View File

@@ -0,0 +1,397 @@
// This file was GENERATED by command:
// pump.py gmock-generated-nice-strict.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock, NaggyMock, and StrictMock.
//
// Given a mock class MockFoo that is created using Google Mock,
// NiceMock<MockFoo> is a subclass of MockFoo that allows
// uninteresting calls (i.e. calls to mock methods that have no
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
// that prints a warning when an uninteresting call occurs, and
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
// uninteresting calls as errors.
//
// Currently a mock is naggy by default, so MockFoo and
// NaggyMock<MockFoo> behave like the same. However, we will soon
// switch the default behavior of mocks to be nice, as that in general
// leads to more maintainable tests. When that happens, MockFoo will
// stop behaving like NaggyMock<MockFoo> and start behaving like
// NiceMock<MockFoo>.
//
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to 10 arguments. Therefore
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
// where MockFoo has a constructor that accepts (int, const char*),
// for example.
//
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
// If a mock method is defined in a base class of MockFoo, the "nice"
// or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported.
//
// Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
template <class MockClass>
class NiceMock : public MockClass {
public:
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
NiceMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
virtual ~NiceMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
};
template <class MockClass>
class NaggyMock : public MockClass {
public:
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
NaggyMock() {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit NaggyMock(const A1& a1) : MockClass(a1) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
virtual ~NaggyMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
};
template <class MockClass>
class StrictMock : public MockClass {
public:
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
StrictMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
virtual ~StrictMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
// The following specializations catch some (relatively more common)
// user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors.
// These specializations are declared but not defined, as NiceMock,
// NaggyMock, and StrictMock cannot be nested.
template <typename MockClass>
class NiceMock<NiceMock<MockClass> >;
template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass>
class StrictMock<NiceMock<MockClass> >;
template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >;
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_

View File

@@ -0,0 +1,161 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-nice-strict.h.
$$
$var n = 10 $$ The maximum arity we support.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock, NaggyMock, and StrictMock.
//
// Given a mock class MockFoo that is created using Google Mock,
// NiceMock<MockFoo> is a subclass of MockFoo that allows
// uninteresting calls (i.e. calls to mock methods that have no
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
// that prints a warning when an uninteresting call occurs, and
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
// uninteresting calls as errors.
//
// Currently a mock is naggy by default, so MockFoo and
// NaggyMock<MockFoo> behave like the same. However, we will soon
// switch the default behavior of mocks to be nice, as that in general
// leads to more maintainable tests. When that happens, MockFoo will
// stop behaving like NaggyMock<MockFoo> and start behaving like
// NiceMock<MockFoo>.
//
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to $n arguments. Therefore
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
// where MockFoo has a constructor that accepts (int, const char*),
// for example.
//
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
// If a mock method is defined in a base class of MockFoo, the "nice"
// or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported.
//
// Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
$range kind 0..2
$for kind [[
$var clazz=[[$if kind==0 [[NiceMock]]
$elif kind==1 [[NaggyMock]]
$else [[StrictMock]]]]
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
$elif kind==1 [[WarnUninterestingCalls]]
$else [[FailUninterestingCalls]]]]
template <class MockClass>
class $clazz : public MockClass {
public:
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
$clazz() {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit $clazz(const A1& a1) : MockClass(a1) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename A$j]]>
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
]]
virtual ~$clazz() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
};
]]
// The following specializations catch some (relatively more common)
// user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors.
// These specializations are declared but not defined, as NiceMock,
// NaggyMock, and StrictMock cannot be nested.
template <typename MockClass>
class NiceMock<NiceMock<MockClass> >;
template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass>
class StrictMock<NiceMock<MockClass> >;
template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >;
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,233 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some actions that depend on gmock-generated-actions.h.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <algorithm>
#include "gmock/gmock-generated-actions.h"
namespace testing {
namespace internal {
// Implements the Invoke(f) action. The template argument
// FunctionImpl is the implementation type of f, which can be either a
// function pointer or a functor. Invoke(f) can be used as an
// Action<F> as long as f's type is compatible with F (i.e. f can be
// assigned to a tr1::function<F>).
template <typename FunctionImpl>
class InvokeAction {
public:
// The c'tor makes a copy of function_impl (either a function
// pointer or a functor).
explicit InvokeAction(FunctionImpl function_impl)
: function_impl_(function_impl) {}
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) {
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
}
private:
FunctionImpl function_impl_;
GTEST_DISALLOW_ASSIGN_(InvokeAction);
};
// Implements the Invoke(object_ptr, &Class::Method) action.
template <class Class, typename MethodPtr>
class InvokeMethodAction {
public:
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) const {
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
obj_ptr_, method_ptr_, args);
}
private:
Class* const obj_ptr_;
const MethodPtr method_ptr_;
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
};
} // namespace internal
// Various overloads for Invoke().
// Creates an action that invokes 'function_impl' with the mock
// function's arguments.
template <typename FunctionImpl>
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
FunctionImpl function_impl) {
return MakePolymorphicAction(
internal::InvokeAction<FunctionImpl>(function_impl));
}
// Creates an action that invokes the given method on the given object
// with the mock function's arguments.
template <class Class, typename MethodPtr>
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
Class* obj_ptr, MethodPtr method_ptr) {
return MakePolymorphicAction(
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
}
// WithoutArgs(inner_action) can be used in a mock function with a
// non-empty argument list to perform inner_action, which takes no
// argument. In other words, it adapts an action accepting no
// argument to one that accepts (and ignores) arguments.
template <typename InnerAction>
inline internal::WithArgsAction<InnerAction>
WithoutArgs(const InnerAction& action) {
return internal::WithArgsAction<InnerAction>(action);
}
// WithArg<k>(an_action) creates an action that passes the k-th
// (0-based) argument of the mock function to an_action and performs
// it. It adapts an action accepting one argument to one that accepts
// multiple arguments. For convenience, we also provide
// WithArgs<k>(an_action) (defined below) as a synonym.
template <int k, typename InnerAction>
inline internal::WithArgsAction<InnerAction, k>
WithArg(const InnerAction& action) {
return internal::WithArgsAction<InnerAction, k>(action);
}
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
// Action ReturnArg<k>() returns the k-th argument of the mock function.
ACTION_TEMPLATE(ReturnArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
return std::tr1::get<k>(args);
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
ACTION_TEMPLATE(SaveArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
*pointer = ::std::tr1::get<k>(args);
}
// Action SaveArgPointee<k>(pointer) saves the value pointed to
// by the k-th (0-based) argument of the mock function to *pointer.
ACTION_TEMPLATE(SaveArgPointee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
*pointer = *::std::tr1::get<k>(args);
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
ACTION_TEMPLATE(SetArgReferee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(value)) {
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
// Ensures that argument #k is a reference. If you get a compiler
// error on the next line, you are using SetArgReferee<k>(value) in
// a mock function whose k-th (0-based) argument is not a reference.
GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
SetArgReferee_must_be_used_with_a_reference_argument);
::std::tr1::get<k>(args) = value;
}
// Action SetArrayArgument<k>(first, last) copies the elements in
// source range [first, last) to the array pointed to by the k-th
// (0-based) argument, which can be either a pointer or an
// iterator. The action does not take ownership of the elements in the
// source range.
ACTION_TEMPLATE(SetArrayArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_2_VALUE_PARAMS(first, last)) {
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
// 4996 (Function call with parameters that may be unsafe) there.
#ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4996) // Temporarily disables warning 4996.
#endif
::std::copy(first, last, ::std::tr1::get<k>(args));
#ifdef _MSC_VER
# pragma warning(pop) // Restores the warning state.
#endif
}
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
// function.
ACTION_TEMPLATE(DeleteArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
delete ::std::tr1::get<k>(args);
}
// This action returns the value pointed to by 'pointer'.
ACTION_P(ReturnPointee, pointer) { return *pointer; }
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
// Suppresses the 'unreachable code' warning that VC generates in opt modes.
# ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4702) // Temporarily disables warning 4702.
# endif
ACTION_P(Throw, exception) { throw exception; }
# ifdef _MSC_VER
# pragma warning(pop) // Restores the warning state.
# endif
#endif // GTEST_HAS_EXCEPTIONS
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_

View File

@@ -0,0 +1,58 @@
// Copyright 2013, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: marcus.boerger@google.com (Marcus Boerger)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some matchers that depend on gmock-generated-matchers.h.
//
// Note that tests are implemented in gmock-matchers_test.cc rather than
// gmock-more-matchers-test.cc.
#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
#define GMOCK_GMOCK_MORE_MATCHERS_H_
#include "gmock/gmock-generated-matchers.h"
namespace testing {
// Defines a matcher that matches an empty container. The container must
// support both size() and empty(), which all STL-like containers provide.
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
if (arg.empty()) {
return true;
}
*result_listener << "whose size is " << arg.size();
return false;
}
} // namespace testing
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This is the main header file a user should include.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax:
//
// ON_CALL(mock_object.Method(...))
// .With(...) ?
// .WillByDefault(...);
//
// where With() is optional and WillByDefault() must appear exactly
// once.
//
// EXPECT_CALL(mock_object.Method(...))
// .With(...) ?
// .Times(...) ?
// .InSequence(...) *
// .WillOnce(...) *
// .WillRepeatedly(...) ?
// .RetiresOnSaturation() ? ;
//
// where all clauses are optional and WillOnce() can be repeated.
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
// Declares Google Mock flags that we want a user to use programmatically.
GMOCK_DECLARE_bool_(catch_leaked_mocks);
GMOCK_DECLARE_string_(verbose);
// Initializes Google Mock. This must be called before running the
// tests. In particular, it parses the command line for the flags
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
// it is removed from argv, and *argc is decremented.
//
// No value is returned. Instead, the Google Mock flag variables are
// updated.
//
// Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't
// been done.
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
// This overloaded version can be used in Windows programs compiled in
// UNICODE mode.
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_

View File

@@ -0,0 +1,279 @@
// This file was GENERATED by command:
// pump.py gmock-generated-internal-utils.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file contains template meta-programming utility classes needed
// for implementing Google Mock.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#include "gmock/internal/gmock-port.h"
namespace testing {
template <typename T>
class Matcher;
namespace internal {
// An IgnoredValue object can be implicitly constructed from ANY value.
// This is used in implementing the IgnoreResult(a) action.
class IgnoredValue {
public:
// This constructor template allows any value to be implicitly
// converted to IgnoredValue. The object has no data member and
// doesn't try to remember anything about the argument. We
// deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit.
template <typename T>
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
};
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
// for the corresponding field in tuple type T.
template <typename Tuple>
struct MatcherTuple;
template <>
struct MatcherTuple< ::std::tr1::tuple<> > {
typedef ::std::tr1::tuple< > type;
};
template <typename A1>
struct MatcherTuple< ::std::tr1::tuple<A1> > {
typedef ::std::tr1::tuple<Matcher<A1> > type;
};
template <typename A1, typename A2>
struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
};
template <typename A1, typename A2, typename A3>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
};
template <typename A1, typename A2, typename A3, typename A4>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
Matcher<A4> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5>, Matcher<A6> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10>
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
A10> > {
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
Matcher<A10> > type;
};
// Template struct Function<F>, where F must be a function type, contains
// the following typedefs:
//
// Result: the function's return type.
// ArgumentN: the type of the N-th argument, where N starts with 1.
// ArgumentTuple: the tuple type consisting of all parameters of F.
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
// parameters of F.
// MakeResultVoid: the function type obtained by substituting void
// for the return type of F.
// MakeResultIgnoredValue:
// the function type obtained by substituting Something
// for the return type of F.
template <typename F>
struct Function;
template <typename R>
struct Function<R()> {
typedef R Result;
typedef ::std::tr1::tuple<> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid();
typedef IgnoredValue MakeResultIgnoredValue();
};
template <typename R, typename A1>
struct Function<R(A1)>
: Function<R()> {
typedef A1 Argument1;
typedef ::std::tr1::tuple<A1> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1);
typedef IgnoredValue MakeResultIgnoredValue(A1);
};
template <typename R, typename A1, typename A2>
struct Function<R(A1, A2)>
: Function<R(A1)> {
typedef A2 Argument2;
typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
};
template <typename R, typename A1, typename A2, typename A3>
struct Function<R(A1, A2, A3)>
: Function<R(A1, A2)> {
typedef A3 Argument3;
typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
};
template <typename R, typename A1, typename A2, typename A3, typename A4>
struct Function<R(A1, A2, A3, A4)>
: Function<R(A1, A2, A3)> {
typedef A4 Argument4;
typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5>
struct Function<R(A1, A2, A3, A4, A5)>
: Function<R(A1, A2, A3, A4)> {
typedef A5 Argument5;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
struct Function<R(A1, A2, A3, A4, A5, A6)>
: Function<R(A1, A2, A3, A4, A5)> {
typedef A6 Argument6;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7>
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
: Function<R(A1, A2, A3, A4, A5, A6)> {
typedef A7 Argument7;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
typedef A8 Argument8;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9>
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
typedef A9 Argument9;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
A9);
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9,
typename A10>
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
typedef A10 Argument10;
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
A10> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
A9, A10);
};
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_

View File

@@ -0,0 +1,136 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-function-mockers.h.
$$
$var n = 10 $$ The maximum arity we support.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file contains template meta-programming utility classes needed
// for implementing Google Mock.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#include "gmock/internal/gmock-port.h"
namespace testing {
template <typename T>
class Matcher;
namespace internal {
// An IgnoredValue object can be implicitly constructed from ANY value.
// This is used in implementing the IgnoreResult(a) action.
class IgnoredValue {
public:
// This constructor template allows any value to be implicitly
// converted to IgnoredValue. The object has no data member and
// doesn't try to remember anything about the argument. We
// deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit.
template <typename T>
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
};
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
// for the corresponding field in tuple type T.
template <typename Tuple>
struct MatcherTuple;
$range i 0..n
$for i [[
$range j 1..i
$var typename_As = [[$for j, [[typename A$j]]]]
$var As = [[$for j, [[A$j]]]]
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
template <$typename_As>
struct MatcherTuple< ::std::tr1::tuple<$As> > {
typedef ::std::tr1::tuple<$matcher_As > type;
};
]]
// Template struct Function<F>, where F must be a function type, contains
// the following typedefs:
//
// Result: the function's return type.
// ArgumentN: the type of the N-th argument, where N starts with 1.
// ArgumentTuple: the tuple type consisting of all parameters of F.
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
// parameters of F.
// MakeResultVoid: the function type obtained by substituting void
// for the return type of F.
// MakeResultIgnoredValue:
// the function type obtained by substituting Something
// for the return type of F.
template <typename F>
struct Function;
template <typename R>
struct Function<R()> {
typedef R Result;
typedef ::std::tr1::tuple<> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid();
typedef IgnoredValue MakeResultIgnoredValue();
};
$range i 1..n
$for i [[
$range j 1..i
$var typename_As = [[$for j [[, typename A$j]]]]
$var As = [[$for j, [[A$j]]]]
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
$range k 1..i-1
$var prev_As = [[$for k, [[A$k]]]]
template <typename R$typename_As>
struct Function<R($As)>
: Function<R($prev_As)> {
typedef A$i Argument$i;
typedef ::std::tr1::tuple<$As> ArgumentTuple;
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
typedef void MakeResultVoid($As);
typedef IgnoredValue MakeResultIgnoredValue($As);
};
]]
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_

View File

@@ -0,0 +1,498 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file defines some utilities useful for implementing Google
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h>
#include <ostream> // NOLINT
#include <string>
#include "gmock/internal/gmock-generated-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
namespace testing {
namespace internal {
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The
// following default implementation is for the case where Pointer is a
// smart pointer.
template <typename Pointer>
struct PointeeOf {
// Smart pointer classes define type element_type as the type of
// their pointees.
typedef typename Pointer::element_type type;
};
// This specialization is for the raw pointer case.
template <typename T>
struct PointeeOf<T*> { typedef T type; }; // NOLINT
// GetRawPointer(p) returns the raw pointer underlying p when p is a
// smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case.
template <typename Pointer>
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
return p.get();
}
// This overloaded version is for the raw pointer case.
template <typename Element>
inline Element* GetRawPointer(Element* p) { return p; }
// This comparator allows linked_ptr to be stored in sets.
template <typename T>
struct LinkedPtrLessThan {
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
const ::testing::internal::linked_ptr<T>& rhs) const {
return lhs.get() < rhs.get();
}
};
// Symbian compilation can be done with wchar_t being either a native
// type or a typedef. Using Google Mock with OpenC without wchar_t
// should require the definition of _STLP_NO_WCHAR_T.
//
// MSVC treats wchar_t as a native type usually, but treats it as the
// same as unsigned short when the compiler option /Zc:wchar_t- is
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
// is a native type.
#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
(defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
// wchar_t is a typedef.
#else
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
#endif
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
// Using them is a bad practice and not portable. So DON'T use them.
//
// Still, Google Mock is designed to work even if the user uses signed
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
// supports them).
//
// To gcc,
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
#ifdef __GNUC__
// signed/unsigned wchar_t are valid types.
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
#endif
// In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type,
// or none of them. This categorization is useful for determining
// when a matcher argument type can be safely converted to another
// type in the implementation of SafeMatcherCast.
enum TypeKind {
kBool, kInteger, kFloatingPoint, kOther
};
// KindOf<T>::value is the kind of type T.
template <typename T> struct KindOf {
enum { value = kOther }; // The default kind.
};
// This macro declares that the kind of 'type' is 'kind'.
#define GMOCK_DECLARE_KIND_(type, kind) \
template <> struct KindOf<type> { enum { value = kind }; }
GMOCK_DECLARE_KIND_(bool, kBool);
// All standard integer types.
GMOCK_DECLARE_KIND_(char, kInteger);
GMOCK_DECLARE_KIND_(signed char, kInteger);
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
// Non-standard integer types.
GMOCK_DECLARE_KIND_(Int64, kInteger);
GMOCK_DECLARE_KIND_(UInt64, kInteger);
// All standard floating-point types.
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
#undef GMOCK_DECLARE_KIND_
// Evaluates to the kind of 'type'.
#define GMOCK_KIND_OF_(type) \
static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value)
// Evaluates to true iff integer type T is signed.
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
// is true iff arithmetic type From can be losslessly converted to
// arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
// raw (i.e. has no CV modifier, is not a pointer, and is not a
// reference) built-in arithmetic types, kFromKind is the kind of
// From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
struct LosslessArithmeticConvertibleImpl : public false_type {};
// Converting bool to bool is lossless.
template <>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
: public true_type {}; // NOLINT
// Converting bool to any integer type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
: public true_type {}; // NOLINT
// Converting bool to any floating-point type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
: public true_type {}; // NOLINT
// Converting an integer to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
: public false_type {}; // NOLINT
// Converting an integer to another non-bool integer is lossless iff
// the target type's range encloses the source type's range.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
: public bool_constant<
// When converting from a smaller size to a larger size, we are
// fine as long as we are not converting from signed to unsigned.
((sizeof(From) < sizeof(To)) &&
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
// When converting between the same size, the signedness must match.
((sizeof(From) == sizeof(To)) &&
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
#undef GMOCK_IS_SIGNED_
// Converting an integer to a floating-point type may be lossy, since
// the format of a floating-point number is implementation-defined.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
: public false_type {}; // NOLINT
// Converting a floating-point to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
: public false_type {}; // NOLINT
// Converting a floating-point to an integer is lossy.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
: public false_type {}; // NOLINT
// Converting a floating-point to another floating-point is lossless
// iff the target type is at least as big as the source type.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<
kFloatingPoint, From, kFloatingPoint, To>
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
// type From can be losslessly converted to arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
// raw (i.e. has no CV modifier, is not a pointer, and is not a
// reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated.
template <typename From, typename To>
struct LosslessArithmeticConvertible
: public LosslessArithmeticConvertibleImpl<
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
class FailureReporterInterface {
public:
// The type of a failure (either non-fatal or fatal).
enum FailureType {
kNonfatal, kFatal
};
virtual ~FailureReporterInterface() {}
// Reports a failure that occurred at the given source file location.
virtual void ReportFailure(FailureType type, const char* file, int line,
const string& message) = 0;
};
// Returns the failure reporter used by Google Mock.
GTEST_API_ FailureReporterInterface* GetFailureReporter();
// Asserts that condition is true; aborts the process with the given
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
// as Google Mock might be used to mock the log sink itself. We
// inline this function to prevent it from showing up in the stack
// trace.
inline void Assert(bool condition, const char* file, int line,
const string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
file, line, msg);
}
}
inline void Assert(bool condition, const char* file, int line) {
Assert(condition, file, line, "Assertion failed.");
}
// Verifies that condition is true; generates a non-fatal failure if
// condition is false.
inline void Expect(bool condition, const char* file, int line,
const string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
file, line, msg);
}
}
inline void Expect(bool condition, const char* file, int line) {
Expect(condition, file, line, "Expectation failed.");
}
// Severity level of a log.
enum LogSeverity {
kInfo = 0,
kWarning = 1
};
// Valid values for the --gmock_verbose flag.
// All logs (informational and warnings) are printed.
const char kInfoVerbosity[] = "info";
// Only warnings are printed.
const char kWarningVerbosity[] = "warning";
// No logs are printed.
const char kErrorVerbosity[] = "error";
// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity);
// Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
GTEST_API_ void Log(LogSeverity severity,
const string& message,
int stack_frames_to_skip);
// TODO(wan@google.com): group all type utilities together.
// Type traits.
// is_reference<T>::value is non-zero iff T is a reference type.
template <typename T> struct is_reference : public false_type {};
template <typename T> struct is_reference<T&> : public true_type {};
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
template <typename T1, typename T2> struct type_equals : public false_type {};
template <typename T> struct type_equals<T, T> : public true_type {};
// remove_reference<T>::type removes the reference from type T, if any.
template <typename T> struct remove_reference { typedef T type; }; // NOLINT
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
// other types. Useful for saving a copy of a function argument.
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
template <typename T, size_t N> struct DecayArray<T[N]> {
typedef const T* type;
};
// Sometimes people use arrays whose size is not available at the use site
// (e.g. extern const char kNamePrefix[]). This specialization covers that
// case.
template <typename T> struct DecayArray<T[]> {
typedef const T* type;
};
// Invalid<T>() returns an invalid value of type T. This is useful
// when a value of type T is needed for compilation, but the statement
// will not really be executed (or we don't care if the statement
// crashes).
template <typename T>
inline T Invalid() {
return const_cast<typename remove_reference<T>::type&>(
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
}
template <>
inline void Invalid<void>() {}
// Given a raw type (i.e. having no top-level reference or const
// modifier) RawContainer that's either an STL-style container or a
// native array, class StlContainerView<RawContainer> has the
// following members:
//
// - type is a type that provides an STL-style container view to
// (i.e. implements the STL container concept for) RawContainer;
// - const_reference is a type that provides a reference to a const
// RawContainer;
// - ConstReference(raw_container) returns a const reference to an STL-style
// container view to raw_container, which is a RawContainer.
// - Copy(raw_container) returns an STL-style container view of a
// copy of raw_container, which is a RawContainer.
//
// This generic version is used when RawContainer itself is already an
// STL-style container.
template <class RawContainer>
class StlContainerView {
public:
typedef RawContainer type;
typedef const type& const_reference;
static const_reference ConstReference(const RawContainer& container) {
// Ensures that RawContainer is not a const type.
testing::StaticAssertTypeEq<RawContainer,
GTEST_REMOVE_CONST_(RawContainer)>();
return container;
}
static type Copy(const RawContainer& container) { return container; }
};
// This specialization is used when RawContainer is a native array type.
template <typename Element, size_t N>
class StlContainerView<Element[N]> {
public:
typedef GTEST_REMOVE_CONST_(Element) RawElement;
typedef internal::NativeArray<RawElement> type;
// NativeArray<T> can represent a native array either by value or by
// reference (selected by a constructor argument), so 'const type'
// can be used to reference a const native array. We cannot
// 'typedef const type& const_reference' here, as that would mean
// ConstReference() has to return a reference to a local variable.
typedef const type const_reference;
static const_reference ConstReference(const Element (&array)[N]) {
// Ensures that Element is not a const type.
testing::StaticAssertTypeEq<Element, RawElement>();
#if GTEST_OS_SYMBIAN
// The Nokia Symbian compiler confuses itself in template instantiation
// for this call without the cast to Element*:
// function call '[testing::internal::NativeArray<char *>].NativeArray(
// {lval} const char *[4], long, testing::internal::RelationToSource)'
// does not match
// 'testing::internal::NativeArray<char *>::NativeArray(
// char *const *, unsigned int, testing::internal::RelationToSource)'
// (instantiating: 'testing::internal::ContainsMatcherImpl
// <const char * (&)[4]>::Matches(const char * (&)[4]) const')
// (instantiating: 'testing::internal::StlContainerView<char *[4]>::
// ConstReference(const char * (&)[4])')
// (and though the N parameter type is mismatched in the above explicit
// conversion of it doesn't help - only the conversion of the array).
return type(const_cast<Element*>(&array[0]), N, kReference);
#else
return type(array, N, kReference);
#endif // GTEST_OS_SYMBIAN
}
static type Copy(const Element (&array)[N]) {
#if GTEST_OS_SYMBIAN
return type(const_cast<Element*>(&array[0]), N, kCopy);
#else
return type(array, N, kCopy);
#endif // GTEST_OS_SYMBIAN
}
};
// This specialization is used when RawContainer is a native array
// represented as a (pointer, size) tuple.
template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
public:
typedef GTEST_REMOVE_CONST_(
typename internal::PointeeOf<ElementPointer>::type) RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
static const_reference ConstReference(
const ::std::tr1::tuple<ElementPointer, Size>& array) {
using ::std::tr1::get;
return type(get<0>(array), get<1>(array), kReference);
}
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
using ::std::tr1::get;
return type(get<0>(array), get<1>(array), kCopy);
}
};
// The following specialization prevents the user from instantiating
// StlContainer with a reference type.
template <typename T> class StlContainerView<T&>;
// A type transform to remove constness from the first part of a pair.
// Pairs like that are used as the value_type of associative containers,
// and this transform produces a similar but assignable pair.
template <typename T>
struct RemoveConstFromKey {
typedef T type;
};
// Partially specialized to remove constness from std::pair<const K, V>.
template <typename K, typename V>
struct RemoveConstFromKey<std::pair<const K, V> > {
typedef std::pair<K, V> type;
};
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
// std::integral_constant<bool, kValue>.
template <bool kValue>
struct BooleanConstant {};
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_

View File

@@ -0,0 +1,78 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vadimb@google.com (Vadim Berman)
//
// Low-level types and utilities for porting Google Mock to various
// platforms. They are subject to change without notice. DO NOT USE
// THEM IN USER CODE.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <iostream>
// Most of the types needed for porting Google Mock are also required
// for Google Test and are defined in gtest-port.h.
#include "gtest/internal/gtest-linked_ptr.h"
#include "gtest/internal/gtest-port.h"
// To avoid conditional compilation everywhere, we make it
// gmock-port.h's responsibility to #include the header implementing
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
// guaranteed to pull in the tuple header.
// For MS Visual C++, check the compiler version. At least VS 2003 is
// required to compile Google Mock.
#if defined(_MSC_VER) && _MSC_VER < 1310
# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
#endif
// Macro for referencing flags. This is public as we want the user to
// use this syntax to reference Google Mock flags.
#define GMOCK_FLAG(name) FLAGS_gmock_##name
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
#define GMOCK_DECLARE_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
#define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

47
gmock/src/gmock-all.cc Normal file
View File

@@ -0,0 +1,47 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Google C++ Mocking Framework (Google Mock)
//
// This file #includes all Google Mock implementation .cc files. The
// purpose is to allow a user to build Google Mock by compiling this
// file alone.
// This line ensures that gmock.h can be compiled on its own, even
// when it's fused.
#include "gmock/gmock.h"
// The following lines pull in the real gmock *.cc files.
#include "src/gmock-cardinalities.cc"
#include "src/gmock-internal-utils.cc"
#include "src/gmock-matchers.cc"
#include "src/gmock-spec-builders.cc"
#include "src/gmock.cc"

View File

@@ -0,0 +1,156 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements cardinalities.
#include "gmock/gmock-cardinalities.h"
#include <limits.h>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
#include "gmock/internal/gmock-internal-utils.h"
#include "gtest/gtest.h"
namespace testing {
namespace {
// Implements the Between(m, n) cardinality.
class BetweenCardinalityImpl : public CardinalityInterface {
public:
BetweenCardinalityImpl(int min, int max)
: min_(min >= 0 ? min : 0),
max_(max >= min_ ? max : min_) {
std::stringstream ss;
if (min < 0) {
ss << "The invocation lower bound must be >= 0, "
<< "but is actually " << min << ".";
internal::Expect(false, __FILE__, __LINE__, ss.str());
} else if (max < 0) {
ss << "The invocation upper bound must be >= 0, "
<< "but is actually " << max << ".";
internal::Expect(false, __FILE__, __LINE__, ss.str());
} else if (min > max) {
ss << "The invocation upper bound (" << max
<< ") must be >= the invocation lower bound (" << min
<< ").";
internal::Expect(false, __FILE__, __LINE__, ss.str());
}
}
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
virtual int ConservativeLowerBound() const { return min_; }
virtual int ConservativeUpperBound() const { return max_; }
virtual bool IsSatisfiedByCallCount(int call_count) const {
return min_ <= call_count && call_count <= max_;
}
virtual bool IsSaturatedByCallCount(int call_count) const {
return call_count >= max_;
}
virtual void DescribeTo(::std::ostream* os) const;
private:
const int min_;
const int max_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
};
// Formats "n times" in a human-friendly way.
inline internal::string FormatTimes(int n) {
if (n == 1) {
return "once";
} else if (n == 2) {
return "twice";
} else {
std::stringstream ss;
ss << n << " times";
return ss.str();
}
}
// Describes the Between(m, n) cardinality in human-friendly text.
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
if (min_ == 0) {
if (max_ == 0) {
*os << "never called";
} else if (max_ == INT_MAX) {
*os << "called any number of times";
} else {
*os << "called at most " << FormatTimes(max_);
}
} else if (min_ == max_) {
*os << "called " << FormatTimes(min_);
} else if (max_ == INT_MAX) {
*os << "called at least " << FormatTimes(min_);
} else {
// 0 < min_ < max_ < INT_MAX
*os << "called between " << min_ << " and " << max_ << " times";
}
}
} // Unnamed namespace
// Describes the given call count to an ostream.
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os) {
if (actual_call_count > 0) {
*os << "called " << FormatTimes(actual_call_count);
} else {
*os << "never called";
}
}
// Creates a cardinality that allows at least n calls.
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
// Creates a cardinality that allows at most n calls.
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
// Creates a cardinality that allows any number of calls.
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
// Creates a cardinality that allows between min and max calls.
GTEST_API_ Cardinality Between(int min, int max) {
return Cardinality(new BetweenCardinalityImpl(min, max));
}
// Creates a cardinality that allows exactly n calls.
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
} // namespace testing

View File

@@ -0,0 +1,174 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file defines some utilities useful for implementing Google
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
#include "gmock/internal/gmock-internal-utils.h"
#include <ctype.h>
#include <ostream> // NOLINT
#include <string>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
namespace testing {
namespace internal {
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
string result;
char prev_char = '\0';
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
// We don't care about the current locale as the input is
// guaranteed to be a valid C++ identifier name.
const bool starts_new_word = IsUpper(*p) ||
(!IsAlpha(prev_char) && IsLower(*p)) ||
(!IsDigit(prev_char) && IsDigit(*p));
if (IsAlNum(*p)) {
if (starts_new_word && result != "")
result += ' ';
result += ToLower(*p);
}
}
return result;
}
// This class reports Google Mock failures as Google Test failures. A
// user can define another class in a similar fashion if he intends to
// use Google Mock with a testing framework other than Google Test.
class GoogleTestFailureReporter : public FailureReporterInterface {
public:
virtual void ReportFailure(FailureType type, const char* file, int line,
const string& message) {
AssertHelper(type == kFatal ?
TestPartResult::kFatalFailure :
TestPartResult::kNonFatalFailure,
file,
line,
message.c_str()) = Message();
if (type == kFatal) {
posix::Abort();
}
}
};
// Returns the global failure reporter. Will create a
// GoogleTestFailureReporter and return it the first time called.
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
// Points to the global failure reporter used by Google Mock. gcc
// guarantees that the following use of failure_reporter is
// thread-safe. We may need to add additional synchronization to
// protect failure_reporter if we port Google Mock to other
// compilers.
static FailureReporterInterface* const failure_reporter =
new GoogleTestFailureReporter();
return failure_reporter;
}
// Protects global resources (stdout in particular) used by Log().
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info.
return true;
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
// Always hide it if --gmock_verbose=error.
return false;
} else {
// If --gmock_verbose is neither "info" nor "error", we treat it
// as "warning" (its default value).
return severity == kWarning;
}
}
// Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
GTEST_API_ void Log(LogSeverity severity,
const string& message,
int stack_frames_to_skip) {
if (!LogIsVisible(severity))
return;
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
// macro.
if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
std::cout << "\nGMOCK WARNING:";
}
// Pre-pends a new-line to message if it doesn't start with one.
if (message.empty() || message[0] != '\n') {
std::cout << "\n";
}
std::cout << message;
if (stack_frames_to_skip >= 0) {
#ifdef NDEBUG
// In opt mode, we have to be conservative and skip no stack frame.
const int actual_to_skip = 0;
#else
// In dbg mode, we can do what the caller tell us to do (plus one
// for skipping this function's stack frame).
const int actual_to_skip = stack_frames_to_skip + 1;
#endif // NDEBUG
// Appends a new-line to message if it doesn't end with one.
if (!message.empty() && *message.rbegin() != '\n') {
std::cout << "\n";
}
std::cout << "Stack trace:\n"
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
::testing::UnitTest::GetInstance(), actual_to_skip);
}
std::cout << ::std::flush;
}
} // namespace internal
} // namespace testing

498
gmock/src/gmock-matchers.cc Normal file
View File

@@ -0,0 +1,498 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements Matcher<const string&>, Matcher<string>, and
// utilities for defining matchers.
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
#include <sstream>
#include <string>
namespace testing {
// Constructs a matcher that matches a const string& whose value is
// equal to s.
Matcher<const internal::string&>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const string& whose value is
// equal to s.
Matcher<const internal::string&>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a string whose value is equal to s.
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a string whose value is equal to s.
Matcher<internal::string>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
#if GTEST_HAS_STRING_PIECE_
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
#endif // GTEST_HAS_STRING_PIECE_
namespace internal {
// Joins a vector of strings as if they are fields of a tuple; returns
// the joined string.
GTEST_API_ string JoinAsTuple(const Strings& fields) {
switch (fields.size()) {
case 0:
return "";
case 1:
return fields[0];
default:
string result = "(" + fields[0];
for (size_t i = 1; i < fields.size(); i++) {
result += ", ";
result += fields[i];
}
result += ")";
return result;
}
}
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the
// negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters.
GTEST_API_ string FormatMatcherDescription(bool negation,
const char* matcher_name,
const Strings& param_values) {
string result = ConvertIdentifierNameToWords(matcher_name);
if (param_values.size() >= 1)
result += " " + JoinAsTuple(param_values);
return negation ? "not (" + result + ")" : result;
}
// FindMaxBipartiteMatching and its helper class.
//
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
// bipartite matching. Flow is considered to be from left to right.
// There is an implicit source node that is connected to all of the left
// nodes, and an implicit sink node that is connected to all of the
// right nodes. All edges have unit capacity.
//
// Neither the flow graph nor the residual flow graph are represented
// explicitly. Instead, they are implied by the information in 'graph' and
// a vector<int> called 'left_' whose elements are initialized to the
// value kUnused. This represents the initial state of the algorithm,
// where the flow graph is empty, and the residual flow graph has the
// following edges:
// - An edge from source to each left_ node
// - An edge from each right_ node to sink
// - An edge from each left_ node to each right_ node, if the
// corresponding edge exists in 'graph'.
//
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
// nodes l and r. This induces the following changes:
// - The edges (source, l), (l, r), and (r, sink) are added to the
// flow graph.
// - The same three edges are removed from the residual flow graph.
// - The reverse edges (l, source), (r, l), and (sink, r) are added
// to the residual flow graph, which is a directional graph
// representing unused flow capacity.
//
// When the method augments a flow (moving left_[l] from some r1 to some
// other r2), this can be thought of as "undoing" the above steps with
// respect to r1 and "redoing" them with respect to r2.
//
// It bears repeating that the flow graph and residual flow graph are
// never represented explicitly, but can be derived by looking at the
// information in 'graph' and in left_.
//
// As an optimization, there is a second vector<int> called right_ which
// does not provide any new information. Instead, it enables more
// efficient queries about edges entering or leaving the right-side nodes
// of the flow or residual flow graphs. The following invariants are
// maintained:
//
// left[l] == kUnused or right[left[l]] == l
// right[r] == kUnused or left[right[r]] == r
//
// . [ source ] .
// . ||| .
// . ||| .
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
// . || | | .
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
// . | || .
// . \----> left[2]=2 ------> right[2]=2 --\|| .
// . ||| .
// . elements matchers vvv .
// . [ sink ] .
//
// See Also:
// [1] Cormen, et al (2001). "Section 26.2: The FordFulkerson method".
// "Introduction to Algorithms (Second ed.)", pp. 651664.
// [2] "FordFulkerson algorithm", Wikipedia,
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
class MaxBipartiteMatchState {
public:
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
right_(graph_->RhsSize(), kUnused) {
}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
// 'seen' is used for path finding { 0: unseen, 1: seen }.
::std::vector<char> seen;
// Searches the residual flow graph for a path from each left node to
// the sink in the residual flow graph, and if one is found, add flow
// to the graph. It's okay to search through the left nodes once. The
// edge from the implicit source node to each previously-visited left
// node will have flow if that left node has any path to the sink
// whatsoever. Subsequent augmentations can only add flow to the
// network, and cannot take away that previous flow unit from the source.
// Since the source-to-left edge can only carry one flow unit (or,
// each element can be matched to only one matcher), there is no need
// to visit the left nodes more than once looking for augmented paths.
// The flow is known to be possible or impossible by looking at the
// node once.
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
// Reset the path-marking vector and try to find a path from
// source to sink starting at the left_[ilhs] node.
GTEST_CHECK_(left_[ilhs] == kUnused)
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
seen.assign(graph_->RhsSize(), 0);
TryAugment(ilhs, &seen);
}
ElementMatcherPairs result;
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
size_t irhs = left_[ilhs];
if (irhs == kUnused) continue;
result.push_back(ElementMatcherPair(ilhs, irhs));
}
return result;
}
private:
static const size_t kUnused = static_cast<size_t>(-1);
// Perform a depth-first search from left node ilhs to the sink. If a
// path is found, flow is added to the network by linking the left and
// right vector elements corresponding each segment of the path.
// Returns true if a path to sink was found, which means that a unit of
// flow was added to the network. The 'seen' vector elements correspond
// to right nodes and are marked to eliminate cycles from the search.
//
// Left nodes will only be explored at most once because they
// are accessible from at most one right node in the residual flow
// graph.
//
// Note that left_[ilhs] is the only element of left_ that TryAugment will
// potentially transition from kUnused to another value. Any other
// left_ element holding kUnused before TryAugment will be holding it
// when TryAugment returns.
//
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
if ((*seen)[irhs])
continue;
if (!graph_->HasEdge(ilhs, irhs))
continue;
// There's an available edge from ilhs to irhs.
(*seen)[irhs] = 1;
// Next a search is performed to determine whether
// this edge is a dead end or leads to the sink.
//
// right_[irhs] == kUnused means that there is residual flow from
// right node irhs to the sink, so we can use that to finish this
// flow path and return success.
//
// Otherwise there is residual flow to some ilhs. We push flow
// along that path and call ourselves recursively to see if this
// ultimately leads to sink.
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
// Add flow from left_[ilhs] to right_[irhs].
left_[ilhs] = irhs;
right_[irhs] = ilhs;
return true;
}
}
return false;
}
const MatchMatrix* graph_; // not owned
// Each element of the left_ vector represents a left hand side node
// (i.e. an element) and each element of right_ is a right hand side
// node (i.e. a matcher). The values in the left_ vector indicate
// outflow from that node to a node on the the right_ side. The values
// in the right_ indicate inflow, and specify which left_ node is
// feeding that right_ node, if any. For example, left_[3] == 1 means
// there's a flow from element #3 to matcher #1. Such a flow would also
// be redundantly represented in the right_ vector as right_[1] == 3.
// Elements of left_ and right_ are either kUnused or mutually
// referent. Mutually referent means that left_[right_[i]] = i and
// right_[left_[i]] = i.
::std::vector<size_t> left_;
::std::vector<size_t> right_;
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
};
const size_t MaxBipartiteMatchState::kUnused;
GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
::std::ostream* stream) {
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
const char *sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
<< "matcher #" << it->second << ")";
sep = ",";
}
os << "\n}";
}
// Tries to find a pairing, and explains the result.
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
MatchResultListener* listener) {
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
size_t max_flow = matches.size();
bool result = (max_flow == matrix.RhsSize());
if (!result) {
if (listener->IsInterested()) {
*listener << "where no permutation of the elements can "
"satisfy all matchers, and the closest match is "
<< max_flow << " of " << matrix.RhsSize()
<< " matchers with the pairings:\n";
LogElementMatcherPairVec(matches, listener->stream());
}
return false;
}
if (matches.size() > 1) {
if (listener->IsInterested()) {
const char *sep = "where:\n";
for (size_t mi = 0; mi < matches.size(); ++mi) {
*listener << sep << " - element #" << matches[mi].first
<< " is matched by matcher #" << matches[mi].second;
sep = ",\n";
}
}
}
return true;
}
bool MatchMatrix::NextGraph() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
if (!b) {
b = 1;
return true;
}
b = 0;
}
}
return false;
}
void MatchMatrix::Randomize() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
b = static_cast<char>(rand() & 1); // NOLINT
}
}
}
string MatchMatrix::DebugString() const {
::std::stringstream ss;
const char *sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
ss << HasEdge(i, j);
}
sep = ";";
}
return ss.str();
}
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
::std::ostream* os) const {
if (matcher_describers_.empty()) {
*os << "is empty";
return;
}
if (matcher_describers_.size() == 1) {
*os << "has " << Elements(1) << " and that element ";
matcher_describers_[0]->DescribeTo(os);
return;
}
*os << "has " << Elements(matcher_describers_.size())
<< " and there exists some permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep << " - element #" << i << " ";
matcher_describers_[i]->DescribeTo(os);
sep = ", and\n";
}
}
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
::std::ostream* os) const {
if (matcher_describers_.empty()) {
*os << "isn't empty";
return;
}
if (matcher_describers_.size() == 1) {
*os << "doesn't have " << Elements(1)
<< ", or has " << Elements(1) << " that ";
matcher_describers_[0]->DescribeNegationTo(os);
return;
}
*os << "doesn't have " << Elements(matcher_describers_.size())
<< ", or there exists no permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep << " - element #" << i << " ";
matcher_describers_[i]->DescribeTo(os);
sep = ", and\n";
}
}
// Checks that all matchers match at least one element, and that all
// elements match at least one matcher. This enables faster matching
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
bool UnorderedElementsAreMatcherImplBase::
VerifyAllElementsAndMatchersAreMatched(
const ::std::vector<string>& element_printouts,
const MatchMatrix& matrix,
MatchResultListener* listener) const {
bool result = true;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
char matched = matrix.HasEdge(ilhs, irhs);
element_matched[ilhs] |= matched;
matcher_matched[irhs] |= matched;
}
}
{
const char* sep =
"where the following matchers don't match any elements:\n";
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
if (matcher_matched[mi])
continue;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
matcher_describers_[mi]->DescribeTo(listener->stream());
sep = ",\n";
}
}
}
{
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
if (!result) {
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
if (element_matched[ei])
continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
<< element_printouts[ei];
sep = ",\n";
outer_sep = "";
}
}
}
return result;
}
} // namespace internal
} // namespace testing

View File

@@ -0,0 +1,813 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements the spec builder syntax (ON_CALL and
// EXPECT_CALL).
#include "gmock/gmock-spec-builders.h"
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
#include <set>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
# include <unistd.h> // NOLINT
#endif
namespace testing {
namespace internal {
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
// Logs a message including file and line number information.
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
const string& message) {
::std::ostringstream s;
s << file << ":" << line << ": " << message << ::std::endl;
Log(severity, s.str(), 0);
}
// Constructs an ExpectationBase object.
ExpectationBase::ExpectationBase(const char* a_file,
int a_line,
const string& a_source_text)
: file_(a_file),
line_(a_line),
source_text_(a_source_text),
cardinality_specified_(false),
cardinality_(Exactly(1)),
call_count_(0),
retired_(false),
extra_matcher_specified_(false),
repeated_action_specified_(false),
retires_on_saturation_(false),
last_clause_(kNone),
action_count_checked_(false) {}
// Destructs an ExpectationBase object.
ExpectationBase::~ExpectationBase() {}
// Explicitly specifies the cardinality of this expectation. Used by
// the subclasses to implement the .Times() clause.
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
cardinality_specified_ = true;
cardinality_ = a_cardinality;
}
// Retires all pre-requisites of this expectation.
void ExpectationBase::RetireAllPreRequisites()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
if (is_retired()) {
// We can take this short-cut as we never retire an expectation
// until we have retired all its pre-requisites.
return;
}
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
it != immediate_prerequisites_.end(); ++it) {
ExpectationBase* const prerequisite = it->expectation_base().get();
if (!prerequisite->is_retired()) {
prerequisite->RetireAllPreRequisites();
prerequisite->Retire();
}
}
}
// Returns true iff all pre-requisites of this expectation have been
// satisfied.
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
it != immediate_prerequisites_.end(); ++it) {
if (!(it->expectation_base()->IsSatisfied()) ||
!(it->expectation_base()->AllPrerequisitesAreSatisfied()))
return false;
}
return true;
}
// Adds unsatisfied pre-requisites of this expectation to 'result'.
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
it != immediate_prerequisites_.end(); ++it) {
if (it->expectation_base()->IsSatisfied()) {
// If *it is satisfied and has a call count of 0, some of its
// pre-requisites may not be satisfied yet.
if (it->expectation_base()->call_count_ == 0) {
it->expectation_base()->FindUnsatisfiedPrerequisites(result);
}
} else {
// Now that we know *it is unsatisfied, we are not so interested
// in whether its pre-requisites are satisfied. Therefore we
// don't recursively call FindUnsatisfiedPrerequisites() here.
*result += *it;
}
}
}
// Describes how many times a function call matching this
// expectation has occurred.
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
// Describes how many times the function is expected to be called.
*os << " Expected: to be ";
cardinality().DescribeTo(os);
*os << "\n Actual: ";
Cardinality::DescribeActualCallCountTo(call_count(), os);
// Describes the state of the expectation (e.g. is it satisfied?
// is it active?).
*os << " - " << (IsOverSaturated() ? "over-saturated" :
IsSaturated() ? "saturated" :
IsSatisfied() ? "satisfied" : "unsatisfied")
<< " and "
<< (is_retired() ? "retired" : "active");
}
// Checks the action count (i.e. the number of WillOnce() and
// WillRepeatedly() clauses) against the cardinality if this hasn't
// been done before. Prints a warning if there are too many or too
// few actions.
void ExpectationBase::CheckActionCountIfNotDone() const
GTEST_LOCK_EXCLUDED_(mutex_) {
bool should_check = false;
{
MutexLock l(&mutex_);
if (!action_count_checked_) {
action_count_checked_ = true;
should_check = true;
}
}
if (should_check) {
if (!cardinality_specified_) {
// The cardinality was inferred - no need to check the action
// count against it.
return;
}
// The cardinality was explicitly specified.
const int action_count = static_cast<int>(untyped_actions_.size());
const int upper_bound = cardinality().ConservativeUpperBound();
const int lower_bound = cardinality().ConservativeLowerBound();
bool too_many; // True if there are too many actions, or false
// if there are too few.
if (action_count > upper_bound ||
(action_count == upper_bound && repeated_action_specified_)) {
too_many = true;
} else if (0 < action_count && action_count < lower_bound &&
!repeated_action_specified_) {
too_many = false;
} else {
return;
}
::std::stringstream ss;
DescribeLocationTo(&ss);
ss << "Too " << (too_many ? "many" : "few")
<< " actions specified in " << source_text() << "...\n"
<< "Expected to be ";
cardinality().DescribeTo(&ss);
ss << ", but has " << (too_many ? "" : "only ")
<< action_count << " WillOnce()"
<< (action_count == 1 ? "" : "s");
if (repeated_action_specified_) {
ss << " and a WillRepeatedly()";
}
ss << ".";
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
}
}
// Implements the .Times() clause.
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
if (last_clause_ == kTimes) {
ExpectSpecProperty(false,
".Times() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(last_clause_ < kTimes,
".Times() cannot appear after "
".InSequence(), .WillOnce(), .WillRepeatedly(), "
"or .RetiresOnSaturation().");
}
last_clause_ = kTimes;
SpecifyCardinality(a_cardinality);
}
// Points to the implicit sequence introduced by a living InSequence
// object (if any) in the current thread or NULL.
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
switch (reaction) {
case kAllow:
Log(kInfo, msg, 3);
break;
case kWarn:
Log(kWarning, msg, 3);
break;
default: // FAIL
Expect(false, NULL, -1, msg);
}
}
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
: mock_obj_(NULL), name_("") {}
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
// Sets the mock object this mock method belongs to, and registers
// this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method.
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
{
MutexLock l(&g_gmock_mutex);
mock_obj_ = mock_obj;
}
Mock::Register(mock_obj, this);
}
// Sets the mock object this mock method belongs to, and sets the name
// of the mock function. Will be called upon each invocation of this
// mock function.
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
const char* name)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// We protect name_ under g_gmock_mutex in case this mock function
// is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
mock_obj_ = mock_obj;
name_ = name;
}
// Returns the name of the function being mocked. Must be called
// after RegisterOwner() or SetOwnerAndName() has been called.
const void* UntypedFunctionMockerBase::MockObject() const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const void* mock_obj;
{
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
Assert(mock_obj_ != NULL, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
mock_obj = mock_obj_;
}
return mock_obj;
}
// Returns the name of this mock method. Must be called after
// SetOwnerAndName() has been called.
const char* UntypedFunctionMockerBase::Name() const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const char* name;
{
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
Assert(name_ != NULL, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
name = name_;
}
return name;
}
// Calculates the result of invoking this mock function with the given
// arguments, prints it, and returns it. The caller is responsible
// for deleting the result.
const UntypedActionResultHolderBase*
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
if (untyped_expectations_.size() == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
// We must get Google Mock's reaction on uninteresting calls
// made on this mock object BEFORE performing the action,
// because the action may DELETE the mock object and make the
// following expression meaningless.
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(MockObject());
// True iff we need to print this call's arguments and return
// value. This definition must be kept in sync with
// the behavior of ReportUninterestingCall().
const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it
// only when he wants informational messages.
reaction == kAllow ? LogIsVisible(kInfo) :
// If the user wants this to be a warning, we print it only
// when he wants to see warnings.
reaction == kWarn ? LogIsVisible(kWarning) :
// Otherwise, the user wants this to be an error, and we
// should always print detailed information in the error.
true;
if (!need_to_report_uninteresting_call) {
// Perform the action without printing the call information.
return this->UntypedPerformDefaultAction(untyped_args, "");
}
// Warns about the uninteresting call.
::std::stringstream ss;
this->UntypedDescribeUninterestingCall(untyped_args, &ss);
// Calculates the function result.
const UntypedActionResultHolderBase* const result =
this->UntypedPerformDefaultAction(untyped_args, ss.str());
// Prints the function result.
if (result != NULL)
result->PrintAsActionResult(&ss);
ReportUninterestingCall(reaction, ss.str());
return result;
}
bool is_excessive = false;
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
const void* untyped_action = NULL;
// The UntypedFindMatchingExpectation() function acquires and
// releases g_gmock_mutex.
const ExpectationBase* const untyped_expectation =
this->UntypedFindMatchingExpectation(
untyped_args, &untyped_action, &is_excessive,
&ss, &why);
const bool found = untyped_expectation != NULL;
// True iff we need to print the call's arguments and return value.
// This definition must be kept in sync with the uses of Expect()
// and Log() in this function.
const bool need_to_report_call =
!found || is_excessive || LogIsVisible(kInfo);
if (!need_to_report_call) {
// Perform the action without printing the call information.
return
untyped_action == NULL ?
this->UntypedPerformDefaultAction(untyped_args, "") :
this->UntypedPerformAction(untyped_action, untyped_args);
}
ss << " Function call: " << Name();
this->UntypedPrintArgs(untyped_args, &ss);
// In case the action deletes a piece of the expectation, we
// generate the message beforehand.
if (found && !is_excessive) {
untyped_expectation->DescribeLocationTo(&loc);
}
const UntypedActionResultHolderBase* const result =
untyped_action == NULL ?
this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
this->UntypedPerformAction(untyped_action, untyped_args);
if (result != NULL)
result->PrintAsActionResult(&ss);
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
Expect(false, NULL, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, untyped_expectation->file(),
untyped_expectation->line(), ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(kInfo, loc.str() + ss.str(), 2);
}
return result;
}
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
for (UntypedExpectations::const_iterator it =
untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
if (it->get() == exp) {
return Expectation(*it);
}
}
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
return Expectation();
// The above statement is just to make the code compile, and will
// never be executed.
}
// Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not.
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
bool expectations_met = true;
for (UntypedExpectations::const_iterator it =
untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
ExpectationBase* const untyped_expectation = it->get();
if (untyped_expectation->IsOverSaturated()) {
// There was an upper-bound violation. Since the error was
// already reported when it occurred, there is no need to do
// anything here.
expectations_met = false;
} else if (!untyped_expectation->IsSatisfied()) {
expectations_met = false;
::std::stringstream ss;
ss << "Actual function call count doesn't match "
<< untyped_expectation->source_text() << "...\n";
// No need to show the source file location of the expectation
// in the description, as the Expect() call that follows already
// takes care of it.
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
untyped_expectation->DescribeCallCountTo(&ss);
Expect(false, untyped_expectation->file(),
untyped_expectation->line(), ss.str());
}
}
// Deleting our expectations may trigger other mock objects to be deleted, for
// example if an action contains a reference counted smart pointer to that
// mock object, and that is the last reference. So if we delete our
// expectations within the context of the global mutex we may deadlock when
// this method is called again. Instead, make a copy of the set of
// expectations to delete, clear our set within the mutex, and then clear the
// copied set outside of it.
UntypedExpectations expectations_to_delete;
untyped_expectations_.swap(expectations_to_delete);
g_gmock_mutex.Unlock();
expectations_to_delete.clear();
g_gmock_mutex.Lock();
return expectations_met;
}
} // namespace internal
// Class Mock.
namespace {
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
// The current state of a mock object. Such information is needed for
// detecting leaked mock objects and explicitly verifying a mock's
// expectations.
struct MockObjectState {
MockObjectState()
: first_used_file(NULL), first_used_line(-1), leakable(false) {}
// Where in the source file an ON_CALL or EXPECT_CALL is first
// invoked on this mock object.
const char* first_used_file;
int first_used_line;
::std::string first_used_test_case;
::std::string first_used_test;
bool leakable; // true iff it's OK to leak the object.
FunctionMockers function_mockers; // All registered methods of the object.
};
// A global registry holding the state of all mock objects that are
// alive. A mock object is added to this registry the first time
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
// is removed from the registry in the mock object's destructor.
class MockObjectRegistry {
public:
// Maps a mock object (identified by its address) to its state.
typedef std::map<const void*, MockObjectState> StateMap;
// This destructor will be called when a program exits, after all
// tests in it have been run. By then, there should be no mock
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
// a macro.
if (!GMOCK_FLAG(catch_leaked_mocks))
return;
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
++it) {
if (it->second.leakable) // The user said it's fine to leak this object.
continue;
// TODO(wan@google.com): Print the type of the leaked object.
// This can help the user identify the leaked object.
std::cout << "\n";
const MockObjectState& state = it->second;
std::cout << internal::FormatFileLocation(state.first_used_file,
state.first_used_line);
std::cout << " ERROR: this mock object";
if (state.first_used_test != "") {
std::cout << " (used in test " << state.first_used_test_case << "."
<< state.first_used_test << ")";
}
std::cout << " should be deleted but never is. Its address is @"
<< it->first << ".";
leaked_count++;
}
if (leaked_count > 0) {
std::cout << "\nERROR: " << leaked_count
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects")
<< " found at program exit.\n";
std::cout.flush();
::std::cerr.flush();
// RUN_ALL_TESTS() has already returned when this destructor is
// called. Therefore we cannot use the normal Google Test
// failure reporting mechanism.
_exit(1); // We cannot call exit() as it is not reentrant and
// may already have been called.
}
}
StateMap& states() { return states_; }
private:
StateMap states_;
};
// Protected by g_gmock_mutex.
MockObjectRegistry g_mock_object_registry;
// Maps a mock object to the reaction Google Mock should have when an
// uninteresting method is called. Protected by g_gmock_mutex.
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
// Sets the reaction Google Mock should have when an uninteresting
// method of the given mock object is called.
void SetReactionOnUninterestingCalls(const void* mock_obj,
internal::CallReaction reaction)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_uninteresting_call_reaction[mock_obj] = reaction;
}
} // namespace
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
void Mock::AllowUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
}
// Tells Google Mock to warn the user about uninteresting calls on the
// given mock object.
void Mock::WarnUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
}
// Tells Google Mock to fail uninteresting calls on the given mock
// object.
void Mock::FailUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
}
// Tells Google Mock the given mock object is being destroyed and its
// entry in the call-reaction table should be removed.
void Mock::UnregisterCallReaction(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_uninteresting_call_reaction.erase(mock_obj);
}
// Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object.
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
internal::kDefault : g_uninteresting_call_reaction[mock_obj];
}
// Tells Google Mock to ignore mock_obj when checking for leaked mock
// objects.
void Mock::AllowLeak(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].leakable = true;
}
// Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectations(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return VerifyAndClearExpectationsLocked(mock_obj);
}
// Verifies all expectations on the given mock object and clears its
// default actions and expectations. Returns true iff the
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
ClearDefaultActionsLocked(mock_obj);
return VerifyAndClearExpectationsLocked(mock_obj);
}
// Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) {
// No EXPECT_CALL() was set on the given mock object.
return true;
}
// Verifies and clears the expectations on each mock method in the
// given mock object.
bool expectations_met = true;
FunctionMockers& mockers =
g_mock_object_registry.states()[mock_obj].function_mockers;
for (FunctionMockers::const_iterator it = mockers.begin();
it != mockers.end(); ++it) {
if (!(*it)->VerifyAndClearExpectationsLocked()) {
expectations_met = false;
}
}
// We don't clear the content of mockers, as they may still be
// needed by ClearDefaultActionsLocked().
return expectations_met;
}
// Registers a mock object and a mock method it owns.
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
}
// Tells Google Mock where in the source code mock_obj is used in an
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
// information helps the user identify which object it is.
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
const char* file, int line)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
if (state.first_used_file == NULL) {
state.first_used_file = file;
state.first_used_line = line;
const TestInfo* const test_info =
UnitTest::GetInstance()->current_test_info();
if (test_info != NULL) {
// TODO(wan@google.com): record the test case name when the
// ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
// TearDownTestCase().
state.first_used_test_case = test_info->test_case_name();
state.first_used_test = test_info->name();
}
}
}
// Unregisters a mock method; removes the owning mock object from the
// registry when the last mock method associated with it has been
// unregistered. This is called only in the destructor of
// FunctionMockerBase.
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
for (MockObjectRegistry::StateMap::iterator it =
g_mock_object_registry.states().begin();
it != g_mock_object_registry.states().end(); ++it) {
FunctionMockers& mockers = it->second.function_mockers;
if (mockers.erase(mocker) > 0) {
// mocker was in mockers and has been just removed.
if (mockers.empty()) {
g_mock_object_registry.states().erase(it);
}
return;
}
}
}
// Clears all ON_CALL()s set on the given mock object.
void Mock::ClearDefaultActionsLocked(void* mock_obj)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) {
// No ON_CALL() was set on the given mock object.
return;
}
// Clears the default actions for each mock method in the given mock
// object.
FunctionMockers& mockers =
g_mock_object_registry.states()[mock_obj].function_mockers;
for (FunctionMockers::const_iterator it = mockers.begin();
it != mockers.end(); ++it) {
(*it)->ClearDefaultActionsLocked();
}
// We don't clear the content of mockers, as they may still be
// needed by VerifyAndClearExpectationsLocked().
}
Expectation::Expectation() {}
Expectation::Expectation(
const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
: expectation_base_(an_expectation_base) {}
Expectation::~Expectation() {}
// Adds an expectation to a sequence.
void Sequence::AddExpectation(const Expectation& expectation) const {
if (*last_expectation_ != expectation) {
if (last_expectation_->expectation_base() != NULL) {
expectation.expectation_base()->immediate_prerequisites_
+= *last_expectation_;
}
*last_expectation_ = expectation;
}
}
// Creates the implicit sequence if there isn't one.
InSequence::InSequence() {
if (internal::g_gmock_implicit_sequence.get() == NULL) {
internal::g_gmock_implicit_sequence.set(new Sequence);
sequence_created_ = true;
} else {
sequence_created_ = false;
}
}
// Deletes the implicit sequence if it was created by the constructor
// of this object.
InSequence::~InSequence() {
if (sequence_created_) {
delete internal::g_gmock_implicit_sequence.get();
internal::g_gmock_implicit_sequence.set(NULL);
}
}
} // namespace testing

182
gmock/src/gmock.cc Normal file
View File

@@ -0,0 +1,182 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
// TODO(wan@google.com): support using environment variables to
// control the flag values, like what Google Test does.
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
"true iff Google Mock should report leaked mock objects "
"as failures.");
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
" Valid values:\n"
" info - prints all messages.\n"
" warning - prints warnings and errors.\n"
" error - prints errors only.");
namespace internal {
// Parses a string as a command line flag. The string should have the
// format "--gmock_flag=value". When def_optional is true, the
// "=value" part can be omitted.
//
// Returns the value of the flag, or NULL if the parsing failed.
static const char* ParseGoogleMockFlagValue(const char* str,
const char* flag,
bool def_optional) {
// str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL;
// The flag must start with "--gmock_".
const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
// Skips the flag name.
const char* flag_end = str + flag_len;
// When def_optional is true, it's OK to not have a "=value" part.
if (def_optional && (flag_end[0] == '\0')) {
return flag_end;
}
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
if (flag_end[0] != '=') return NULL;
// Returns the string after "=".
return flag_end + 1;
}
// Parses a string for a Google Mock bool flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
bool* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
if (value_str == NULL) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
return true;
}
// Parses a string for a Google Mock string flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
std::string* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
// Aborts if the parsing failed.
if (value_str == NULL) return false;
// Sets *value to the value of the flag.
*value = value_str;
return true;
}
// The internal implementation of InitGoogleMock().
//
// The type parameter CharType can be instantiated to either char or
// wchar_t.
template <typename CharType>
void InitGoogleMockImpl(int* argc, CharType** argv) {
// Makes sure Google Test is initialized. InitGoogleTest() is
// idempotent, so it's fine if the user has already called it.
InitGoogleTest(argc, argv);
if (*argc <= 0) return;
for (int i = 1; i != *argc; i++) {
const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag?
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
&GMOCK_FLAG(catch_leaked_mocks)) ||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
// well.
for (int j = i; j != *argc; j++) {
argv[j] = argv[j + 1];
}
// Decrements the argument count.
(*argc)--;
// We also need to decrement the iterator as we just removed
// an element.
i--;
}
}
}
} // namespace internal
// Initializes Google Mock. This must be called before running the
// tests. In particular, it parses a command line for the flags that
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
// removed from argv, and *argc is decremented.
//
// No value is returned. Instead, the Google Mock flag variables are
// updated.
//
// Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't
// been done.
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
// This overloaded version can be used in Windows programs compiled in
// UNICODE mode.
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
} // namespace testing

54
gmock/src/gmock_main.cc Normal file
View File

@@ -0,0 +1,54 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
// is enabled. For this reason instead of _tmain, main function is used on
// Windows. See the following link to track the current status of this bug:
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
#if GTEST_OS_WINDOWS_MOBILE
# include <tchar.h> // NOLINT
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else
GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n";
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
// no need for calling testing::InitGoogleTest() separately.
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Sat Nov 21 18:19:09 EST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip

104
gradlew vendored
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -6,42 +6,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -56,9 +20,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -85,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

14
gradlew.bat vendored
View File

@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

43
hal/.styleguide Normal file
View File

@@ -0,0 +1,43 @@
cppHeaderFileInclude {
\.h$
\.hpp$
\.inc$
}
cppSrcFileInclude {
\.cpp$
}
generatedFileExclude {
gmock/
ni-libraries/include/
ni-libraries/lib/
hal/src/main/native/athena/ctre/
hal/src/main/native/athena/frccansae/
hal/src/main/native/athena/visa/
hal/src/main/native/include/ctre/
UsageReporting\.h$
}
modifiableFileExclude {
wpilibj/src/arm-linux-jni/
wpilibj/src/main/native/cpp/
\.patch$
\.png$
\.py$
\.so$
}
includeOtherLibs {
^FRC_FPGA_ChipObject/
^FRC_NetworkCommunication/
^i2clib/
^llvm/
^opencv2/
^spilib/
^support/
}
includeProject {
^ctre/
}

View File

@@ -1,47 +1,222 @@
// There are two hal libraries that are built
// - Desktop which is used by simulation (gcc/msvc)
// - Athena which is used by the roborio (arm)
apply plugin: 'cpp'
apply plugin: 'google-test'
apply plugin: 'visual-studio'
apply plugin: 'edu.wpi.first.NativeUtils'
apply from: '../config.gradle'
ext.addHalToLinker = { binary->
if (binary.targetPlatform.architecture.name == 'athena') {
binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
} else {
binary.lib project: ':hal', library: 'halSim', linkage: 'shared'
}
}
model {
components {
HALAthena(NativeLibrarySpec) {
targetPlatform 'arm'
tasks.withType(CppCompile) {
dependsOn addNiLibraryLinks
}
sources {
cpp {
source {
srcDirs = ["lib/Athena", "lib/Athena/FRC_FPGA_ChipObject", "lib/Shared"]
includes = ["**/*.cpp"]
dependencyConfigs {
wpiutil(DependencyConfig) {
groupId = 'edu.wpi.first.wpiutil'
artifactId = 'wpiutil-cpp'
headerClassifier = 'headers'
ext = 'zip'
version = '3.+'
sharedConfigs = [ halAthena: [], halSim: [], halDev: [], halSimTestingBaseTest: [] ]
staticConfigs = [ halSimStaticDeps: [] ]
}
}
// Exports config is a utility to enable exporting all symbols in a C++ library on windows to a DLL.
// This removes the need for DllExport on a library. However, the gradle C++ builder has a bug
// where some extra symbols are added that cannot be resolved at link time. This configuration
// lets you specify specific symbols to exlude from exporting.
exportsConfigs {
halSim(ExportsConfig) {
x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
'_CT??_R0?AVbad_cast',
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
'_TI5?AVfailure' ]
x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
'_CT??_R0?AVbad_cast',
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
'_TI5?AVfailure' ]
}
halSimStaticDeps(ExportsConfig) {
x86SymbolFilter = { symbols->
def retList = []
symbols.each { symbol->
if (symbol.startsWith('HAL_')) {
retList << symbol
}
exportedHeaders {
srcDirs = ["include", "lib/Athena", "lib/Athena/FRC_FPGA_ChipObject", "lib/Shared"]
}
return retList
}
x64SymbolFilter = { symbols->
def retList = []
symbols.each { symbol->
if (symbol.startsWith('HAL_')) {
retList << symbol
}
}
return retList
}
}
}
components {
if (!project.hasProperty('skipAthena')) {
halAthena(NativeLibrarySpec) {
baseName = 'wpiHal'
sources {
cpp {
source {
srcDirs = [ 'src/main/native/shared', 'src/main/native/athena' ]
includes = ["**/*.cpp"]
}
exportedHeaders {
srcDirs = ["src/main/native/include"]
}
}
}
binaries.all { binary->
if (binary.targetPlatform.architecture.name != 'athena') {
binary.buildable = false
}
}
}
}
// HALDesktop(NativeLibrarySpec) {
// binaries.all {
// if (toolChain in Gcc){
// cppCompiler.args "-std=c++1y"
// }
// }
//
// sources {
// cpp {
// source {
// srcDirs = ["lib/Desktop", "lib/Shared"]
// includes = ["**/*.cpp"]
// }
// exportedHeaders {
// srcDirs = ["include", "lib/Desktop", "lib/Shared"]
// }
// }
// }
// }
if (!project.hasProperty('onlyAthena')) {
halSim(NativeLibrarySpec) {
baseName = 'wpiHal'
sources {
cpp {
source {
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
includes = ["**/*.cpp"]
}
exportedHeaders {
srcDirs = ["src/main/native/include"]
}
}
}
binaries.all { binary ->
if (binary.targetPlatform.operatingSystem.linux) {
linker.args "-ldl"
}
}
}
if (project.hasProperty('buildHalStaticDeps')) {
halSimStaticDeps(NativeLibrarySpec) {
baseName = 'wpiHal'
binaries {
withType(StaticLibraryBinarySpec) {
buildable = false
}
}
sources {
cpp {
source {
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
includes = ["**/*.cpp"]
}
exportedHeaders {
srcDirs = ["src/main/native/include"]
}
}
}
}
}
}
// The TestingBase library is a workaround for an issue with the GoogleTest plugin.
// The plugin by default will rebuild the entire test source set, which increases
// build time. By testing an empty library, and then just linking the already built component
// into the test, we save the extra build
halSimTestingBase(NativeLibrarySpec) { }
// By default, a development executable will be generated. This is to help the case of
// testing specific functionality of the library.
if (!project.hasProperty('skipDevExe')) {
halDev(NativeExecutableSpec) {
binaries.all {
project.addHalToLinker(it)
}
sources {
cpp {
source {
srcDirs 'src/dev/native/cpp'
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/dev/native/include'
}
}
}
}
}
}
testSuites {
halSimTestingBaseTest {
sources {
cpp.source.srcDir 'src/test/native/cpp'
cpp.exportedHeaders.srcDir 'src/test/native/include'
}
}
}
binaries {
all {
project(':ni-libraries').addNiLibrariesToLinker(it)
}
withType(GoogleTestTestSuiteBinarySpec) {
if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) {
project(':gmock').addGmockToLinker(it)
project.addHalToLinker(it)
} else {
it.buildable = false
}
}
}
tasks {
runCpp(Exec) {
def found = false
$.components.each {
if (it in NativeExecutableSpec && it.name == 'halDev') {
it.binaries.each {
if (!found) {
def arch = it.targetPlatform.architecture.name
if (arch == 'x86-64' || arch == 'x86') {
dependsOn it.tasks.install
commandLine it.tasks.install.runScript
found = true
}
}
}
}
}
}
getHeaders(Task) {
def list = []
$.components.each {
if (it in NativeLibrarySpec && (it.name == 'halAthena' || it.name == 'halSim')) {
it.sources.each {
it.exportedHeaders.srcDirs.each {
list.add(it)
}
}
it.binaries.each {
it.libs.each {
it.includeRoots.each {
list.add(it)
}
}
}
}
}
list = list.unique(false)
doLast {
list.each {
print "WPIHEADER: "
println it
}
}
}
}
}
apply from: 'publish.gradle'

View File

@@ -1,15 +0,0 @@
#pragma once
enum AccelerometerRange {
kRange_2G = 0,
kRange_4G = 1,
kRange_8G = 2,
};
extern "C" {
void setAccelerometerActive(bool);
void setAccelerometerRange(AccelerometerRange);
double getAccelerometerX();
double getAccelerometerY();
double getAccelerometerZ();
}

View File

@@ -1,78 +0,0 @@
#pragma once
#include <stdint.h>
enum AnalogTriggerType
{
kInWindow = 0,
kState = 1,
kRisingPulse = 2,
kFallingPulse = 3
};
extern "C"
{
// Analog output functions
void* initializeAnalogOutputPort(void* port_pointer, int32_t *status);
void freeAnalogOutputPort(void* analog_port_pointer);
void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status);
double getAnalogOutput(void* analog_port_pointer, int32_t *status);
bool checkAnalogOutputChannel(uint32_t pin);
// Analog input functions
void* initializeAnalogInputPort(void* port_pointer, int32_t *status);
void freeAnalogInputPort(void* analog_port_pointer);
bool checkAnalogModule(uint8_t module);
bool checkAnalogInputChannel(uint32_t pin);
void setAnalogSampleRate(double samplesPerSecond, int32_t *status);
float getAnalogSampleRate(int32_t *status);
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t *status);
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t *status);
int16_t getAnalogValue(void* analog_port_pointer, int32_t *status);
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status);
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t *status);
float getAnalogVoltage(void* analog_port_pointer, int32_t *status);
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status);
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t *status);
int32_t getAnalogOffset(void* analog_port_pointer, int32_t *status);
bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status);
void initAccumulator(void* analog_port_pointer, int32_t *status);
void resetAccumulator(void* analog_port_pointer, int32_t *status);
void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *status);
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t *status);
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status);
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status);
void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *count,
int32_t *status);
void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *status);
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status);
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int32_t upper,
int32_t *status);
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower, double upper,
int32_t *status);
void setAnalogTriggerAveraged(void* analog_trigger_pointer, bool useAveragedValue,
int32_t *status);
void setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValue,
int32_t *status);
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status);
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status);
bool getAnalogTriggerOutput(void* analog_trigger_pointer, AnalogTriggerType type,
int32_t *status);
//// Float JNA Hack
// Float
int getAnalogSampleRateIntHack(int32_t *status);
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t *status);
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t *status);
// Doubles
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t *status);
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage, int32_t *status);
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer, int lower, int upper,
int32_t *status);
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <stdint.h>
#include "FRC_NetworkCommunication/CANSessionMux.h"
void canTxSend(uint32_t arbID, uint8_t length, int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
void canTxPackInt8 (uint32_t arbID, uint8_t offset, uint8_t value);
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
uint8_t canTxUnpackInt8 (uint32_t arbID, uint8_t offset);
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
bool canRxReceive(uint32_t arbID);
uint8_t canRxUnpackInt8 (uint32_t arbID, uint8_t offset);
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);

View File

@@ -1,829 +0,0 @@
/**
* @brief CAN TALON SRX driver.
*
* The TALON SRX is designed to instrument all runtime signals periodically.
* The default periods are chosen to support 16 TALONs with 10ms update rate
* for control (throttle or setpoint). However these can be overridden with
* SetStatusFrameRate. @see SetStatusFrameRate
* The getters for these unsolicited signals are auto generated at the bottom
* of this module.
*
* Likewise most control signals are sent periodically using the fire-and-forget
* CAN API. The setters for these unsolicited signals are auto generated at the
* bottom of this module.
*
* Signals that are not available in an unsolicited fashion are the Close Loop
* gains. For teams that have a single profile for their TALON close loop they
* can use either the webpage to configure their TALONs once or set the PIDF,
* Izone, CloseLoopRampRate, etc... once in the robot application. These
* parameters are saved to flash so once they are loaded in the TALON, they
* will persist through power cycles and mode changes.
*
* For teams that have one or two profiles to switch between, they can use the
* same strategy since there are two slots to choose from and the
* ProfileSlotSelect is periodically sent in the 10 ms control frame.
*
* For teams that require changing gains frequently, they can use the soliciting
* API to get and set those parameters. Most likely they will only need to set
* them in a periodic fashion as a function of what motion the application is
* attempting. If this API is used, be mindful of the CAN utilization reported
* in the driver station.
*
* If calling application has used the config routines to configure the
* selected feedback sensor, then all positions are measured in floating point
* precision rotations. All sensor velocities are specified in floating point
* precision RPM.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* HOWEVER, if calling application has not called the config routine for
* selected feedback sensor, then all getters/setters for position/velocity use
* the native engineering units of the Talon SRX firm (just like in 2015).
* Signals explained below.
*
* Encoder position is measured in encoder edges. Every edge is counted
* (similar to roboRIO 4X mode). Analog position is 10 bits, meaning 1024
* ticks per rotation (0V => 3.3V). Use SetFeedbackDeviceSelect to select
* which sensor type you need. Once you do that you can use GetSensorPosition()
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by
* default). If a relative sensor is selected, you can zero (or change the
* current value) using SetSensorPosition.
*
* Analog Input and quadrature position (and velocity) are also explicitly
* reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
* These signals are available all the time, regardless of what sensor is
* selected at a rate of 100ms. This allows easy instrumentation for "in the
* pits" checking of all sensors regardless of modeselect. The 100ms rate is
* overridable for teams who want to acquire sensor data for processing, not
* just instrumentation. Or just select the sensor using
* SetFeedbackDeviceSelect to get it at 20ms.
*
* Velocity is in position ticks / 100ms.
*
* All output units are in respect to duty cycle (throttle) which is -1023(full
* reverse) to +1023 (full forward). This includes demand (which specifies
* duty cycle when in duty cycle mode) and rampRamp, which is in throttle units
* per 10ms (if nonzero).
*
* Pos and velocity close loops are calc'd as
* err = target - posOrVel.
* iErr += err;
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* output = P X err + I X iErr + D X dErr + F X target
* dErr = err - lastErr
* P, I, and D gains are always positive. F can be negative.
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if
* sensor and motor are out of phase. Similarly feedback sensor can also be
* reversed (multiplied by -1) if you prefer the sensor to be inverted.
*
* P gain is specified in throttle per error tick. For example, a value of 102
* is ~9.9% (which is 102/1023) throttle per 1 ADC unit(10bit) or 1 quadrature
* encoder edge depending on selected sensor.
*
* I gain is specified in throttle per integrated error. For example, a value
* of 10 equates to ~0.99% (which is 10/1023) for each accumulated ADC unit
* (10 bit) or 1 quadrature encoder edge depending on selected sensor.
* Close loop and integral accumulator runs every 1ms.
*
* D gain is specified in throttle per derivative error. For example a value of
* 102 equates to ~9.9% (which is 102/1023) per change of 1 unit (ADC or
* encoder) per ms.
*
* I Zone is specified in the same units as sensor position (ADC units or
* quadrature edges). If pos/vel error is outside of this value, the
* integrated error will auto-clear...
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* ...this is very useful in preventing integral windup and is highly
* recommended if using full PID to keep stability low.
*
* CloseLoopRampRate is in throttle units per 1ms. Set to zero to disable
* ramping. Works the same as RampThrottle but only is in effect when a close
* loop mode and profile slot is selected.
*
* auto generated using spreadsheet and wpiclassgen.py
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
*/
#ifndef CanTalonSRX_H_
#define CanTalonSRX_H_
#include "ctre/ctre.h" //BIT Defines + Typedefs, TALON_Control_6_MotProfAddTrajPoint_t
#include "ctre/CtreCanNode.h"
#include <FRC_NetworkCommunication/CANSessionMux.h> //CAN Comm
#include <map>
#include <atomic>
#include <deque>
#include <mutex>
class CanTalonSRX : public CtreCanNode {
private:
// Use this for determining whether the default move constructor has been
// called; this prevents us from calling the destructor twice.
struct HasBeenMoved {
HasBeenMoved(HasBeenMoved &&other) {
other.moved = true;
moved = false;
}
HasBeenMoved() = default;
std::atomic<bool> moved{false};
operator bool() const { return moved; }
} m_hasBeenMoved;
// Vars for opening a CAN stream if caller needs signals that require
// soliciting
uint32_t _can_h; //!< Session handle for catching response params.
int32_t _can_stat; //!< Session handle status.
struct tCANStreamMessage _msgBuff[20];
static int const kMsgCapacity = 20;
typedef std::map<uint32_t, uint32_t> sigs_t;
// Catches signal updates that are solicited. Expect this to be very few.
sigs_t _sigs;
void OpenSessionIfNeedBe();
void ProcessStreamMessages();
/**
* Called in various places to double check we are using the best control
* frame. If the Talon firmware is too old, use control 1 framing, which
* does not allow setting control signals until robot is enabled. If Talon
* firmware can suport control5, use that since that frame can be
* transmitted during robot-disable. If calling application uses setParam
* to set the signal eLegacyControlMode, caller can force using control1
* if needed for some reason.
*/
void UpdateControlId();
/**
* @return true if Talon is reporting that it supports control5, and therefore
* RIO can send control5 to update control params (even when
* disabled).
*/
bool IsControl5Supported();
/**
* Get a copy of the control frame to send.
* @param [out] pointer to eight byte array to fill.
*/
void GetControlFrameCopy(uint8_t *toFill);
/**
* @return the tx task that transmits Control6 (motion profile control).
* If it's not scheduled, then schedule it. This is part
* of making the lazy-framing that only peforms MotionProf framing
* when needed to save bandwidth.
*/
CtreCanNode::txTask<TALON_Control_6_MotProfAddTrajPoint_t> GetControl6();
/**
* Caller is either pushing a new motion profile point, or is
* calling the Process buffer routine. In either case check our
* flow control to see if we need to start sending control6.
*/
void ReactToMotionProfileCall();
/**
* Update the NextPt signals inside the control frame given the next pt to
* send.
* @param control pointer to the CAN frame payload containing control6. Only
* the signals that serialize the next trajectory point are
* updated from the contents of newPt.
* @param newPt point to the next trajectory that needs to be inserted into
* Talon RAM.
*/
void CopyTrajPtIntoControl(
TALON_Control_6_MotProfAddTrajPoint_t *control,
const TALON_Control_6_MotProfAddTrajPoint_t *newPt);
//---------------------- General Control framing ---------------------------//
/**
* Frame period for control1 or control5, depending on which one we are using.
*/
int _controlPeriodMs = kDefaultControlPeriodMs;
/**
* Frame Period of the motion profile control6 frame.
*/
int _control6PeriodMs = kDefaultControl6PeriodMs;
/**
* When using control5, we still need to send a frame to enable robot. This
* controls the period. This only is used when we are in the control5 state.
* @see ControlFrameSelControl5
*/
int _enablePeriodMs = kDefaultEnablePeriodMs;
/**
* ArbID to use for control frame. Should be either CONTROL_1 or CONTROL_5.
*/
uint32_t _controlFrameArbId;
/**
* Boolean flag to signal calling applications intent to allow using control5
* assuming Talon firmware supports it. This can be cleared to force control1
* framing.
*/
bool _useControl5ifSupported = true;
//--------------------- Buffering Motion Profile ---------------------------//
/**
* Top level Buffer for motion profile trajectory buffering.
* Basically this buffers up the eight byte CAN frame payloads that are
* handshaked into the Talon RAM.
* TODO: Should this be moved into a separate header, and if so where
* logically should it reside?
* TODO: Add compression so that multiple CAN frames can be compressed into
* one exchange.
*/
class TrajectoryBuffer {
public:
void Clear() { _motProfTopBuffer.clear(); }
/**
* push caller's uncompressed simple trajectory point.
*/
void Push(TALON_Control_6_MotProfAddTrajPoint_huff0_t &pt) {
_motProfTopBuffer.push_back(pt);
}
/**
* Get the next trajectory point CAN frame to send.
* Underlying layer may compress the next few points together
* into one control_6 frame.
*/
TALON_Control_6_MotProfAddTrajPoint_t *Front() {
/* TODO : peek ahead and use compression strategies */
_lastFront = _motProfTopBuffer.front();
return (TALON_Control_6_MotProfAddTrajPoint_t *)&_lastFront;
}
void Pop() {
/* TODO : pop multiple points if last front'd point was compressed. */
_motProfTopBuffer.pop_front();
}
unsigned int GetNumTrajectories() { return _motProfTopBuffer.size(); }
bool IsEmpty() { return _motProfTopBuffer.empty(); }
private:
std::deque<TALON_Control_6_MotProfAddTrajPoint_huff0_t> _motProfTopBuffer;
TALON_Control_6_MotProfAddTrajPoint_huff0_t _lastFront;
};
TrajectoryBuffer _motProfTopBuffer;
/**
* To keep buffers from getting out of control, place a cap on the top level
* buffer. Calling application
* can stream addition points as they are fed to Talon.
* Approx memory footprint is this capacity X 8 bytes.
*/
static const int kMotionProfileTopBufferCapacity = 2048;
/**
* Flow control for streaming trajectories.
*/
int32_t _motProfFlowControl = -1;
/**
* Since we may need the MP pts to be emptied into Talon in the background
* make sure the buffering is thread-safe.
*/
std::mutex _mutMotProf;
/**
* Send a one shot frame to set an arbitrary signal.
* Most signals are in the control frame so avoid using this API unless you
* have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed up
* in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this,
* use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so
* GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
/**
* Checks cached CAN frames and updating solicited signals.
*/
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t &rawBits);
public:
// default control update rate is 10ms.
static const int kDefaultControlPeriodMs = 10;
// default enable update rate is 50ms (when using the new control5 frame).
static const int kDefaultEnablePeriodMs = 50;
// Default update rate for motion profile control 6. This only takes effect
// when calling uses MP functions.
static const int kDefaultControl6PeriodMs = 10;
explicit CanTalonSRX(int deviceNumber = 0,
int controlPeriodMs = kDefaultControlPeriodMs,
int enablePeriodMs = kDefaultEnablePeriodMs);
~CanTalonSRX();
void Set(double value);
/* mode select enumerations */
// Demand is 11bit signed duty cycle [-1023,1023].
static const int kMode_DutyCycle = 0;
// Position PIDF.
static const int kMode_PositionCloseLoop = 1;
// Velocity PIDF.
static const int kMode_VelocityCloseLoop = 2;
// Current close loop - not done.
static const int kMode_CurrentCloseLoop = 3;
// Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
static const int kMode_VoltCompen = 4;
// Demand is the 6 bit Device ID of the 'master' TALON SRX.
static const int kMode_SlaveFollower = 5;
// Demand is '0' (Disabled), '1' (Enabled), or '2' (Hold).
static const int kMode_MotionProfile = 6;
// Zero the output (honors brake/coast) regardless of demand.
// Might be useful if we need to change modes but can't atomically
// change all the signals we want in between.
static const int kMode_NoDrive = 15;
/* limit switch enumerations */
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
/* brake override enumerations */
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
static const int kBrakeOverride_OverrideCoast = 1;
static const int kBrakeOverride_OverrideBrake = 2;
/* feedback device enumerations */
static const int kFeedbackDev_DigitalQuadEnc = 0;
static const int kFeedbackDev_AnalogPot = 2;
static const int kFeedbackDev_AnalogEncoder = 3;
static const int kFeedbackDev_CountEveryRisingEdge = 4;
static const int kFeedbackDev_CountEveryFallingEdge = 5;
static const int kFeedbackDev_PosIsPulseWidth = 8;
/* ProfileSlotSelect enumerations*/
static const int kProfileSlotSelect_Slot0 = 0;
static const int kProfileSlotSelect_Slot1 = 1;
/* status frame rate types */
static const int kStatusFrame_General = 0;
static const int kStatusFrame_Feedback = 1;
static const int kStatusFrame_Encoder = 2;
static const int kStatusFrame_AnalogTempVbat = 3;
static const int kStatusFrame_PulseWidthMeas = 4;
static const int kStatusFrame_MotionProfile = 5;
/* Motion Profile status bits */
static const int kMotionProfileFlag_ActTraj_IsValid = 0x1;
static const int kMotionProfileFlag_HasUnderrun = 0x2;
static const int kMotionProfileFlag_IsUnderrun = 0x4;
static const int kMotionProfileFlag_ActTraj_IsLast = 0x8;
static const int kMotionProfileFlag_ActTraj_VelOnly = 0x10;
/* Motion Profile Set Output */
// Motor output is neutral, Motion Profile Executer is not running.
static const int kMotionProf_Disabled = 0;
// Motor output is updated from Motion Profile Executer, MPE will
// process the buffered points.
static const int kMotionProf_Enable = 1;
// Motor output is updated from Motion Profile Executer, MPE will
// stay processing current trajectory point.
static const int kMotionProf_Hold = 2;
/**
* Signal enumeration for generic signal access.
* Although every signal is enumerated, only use this for traffic that must
* be solicited.
* Use the auto generated getters/setters at bottom of this header as much as
* possible.
*/
enum param_t {
eProfileParamSlot0_P = 1,
eProfileParamSlot0_I = 2,
eProfileParamSlot0_D = 3,
eProfileParamSlot0_F = 4,
eProfileParamSlot0_IZone = 5,
eProfileParamSlot0_CloseLoopRampRate = 6,
eProfileParamSlot1_P = 11,
eProfileParamSlot1_I = 12,
eProfileParamSlot1_D = 13,
eProfileParamSlot1_F = 14,
eProfileParamSlot1_IZone = 15,
eProfileParamSlot1_CloseLoopRampRate = 16,
eProfileParamSoftLimitForThreshold = 21,
eProfileParamSoftLimitRevThreshold = 22,
eProfileParamSoftLimitForEnable = 23,
eProfileParamSoftLimitRevEnable = 24,
eOnBoot_BrakeMode = 31,
eOnBoot_LimitSwitch_Forward_NormallyClosed = 32,
eOnBoot_LimitSwitch_Reverse_NormallyClosed = 33,
eOnBoot_LimitSwitch_Forward_Disable = 34,
eOnBoot_LimitSwitch_Reverse_Disable = 35,
eFault_OverTemp = 41,
eFault_UnderVoltage = 42,
eFault_ForLim = 43,
eFault_RevLim = 44,
eFault_HardwareFailure = 45,
eFault_ForSoftLim = 46,
eFault_RevSoftLim = 47,
eStckyFault_OverTemp = 48,
eStckyFault_UnderVoltage = 49,
eStckyFault_ForLim = 50,
eStckyFault_RevLim = 51,
eStckyFault_ForSoftLim = 52,
eStckyFault_RevSoftLim = 53,
eAppliedThrottle = 61,
eCloseLoopErr = 62,
eFeedbackDeviceSelect = 63,
eRevMotDuringCloseLoopEn = 64,
eModeSelect = 65,
eProfileSlotSelect = 66,
eRampThrottle = 67,
eRevFeedbackSensor = 68,
eLimitSwitchEn = 69,
eLimitSwitchClosedFor = 70,
eLimitSwitchClosedRev = 71,
eSensorPosition = 73,
eSensorVelocity = 74,
eCurrent = 75,
eBrakeIsEnabled = 76,
eEncPosition = 77,
eEncVel = 78,
eEncIndexRiseEvents = 79,
eQuadApin = 80,
eQuadBpin = 81,
eQuadIdxpin = 82,
eAnalogInWithOv = 83,
eAnalogInVel = 84,
eTemp = 85,
eBatteryV = 86,
eResetCount = 87,
eResetFlags = 88,
eFirmVers = 89,
eSettingsChanged = 90,
eQuadFilterEn = 91,
ePidIaccum = 93,
eStatus1FrameRate = 94, // TALON_Status_1_General_10ms_t
eStatus2FrameRate = 95, // TALON_Status_2_Feedback_20ms_t
eStatus3FrameRate = 96, // TALON_Status_3_Enc_100ms_t
eStatus4FrameRate = 97, // TALON_Status_4_AinTempVbat_100ms_t
eStatus6FrameRate = 98, // TALON_Status_6_Eol_t
eStatus7FrameRate = 99, // TALON_Status_7_Debug_200ms_t
eClearPositionOnIdx = 100,
// reserved,
// reserved,
// reserved,
ePeakPosOutput = 104,
eNominalPosOutput = 105,
ePeakNegOutput = 106,
eNominalNegOutput = 107,
eQuadIdxPolarity = 108,
eStatus8FrameRate = 109, // TALON_Status_8_PulseWid_100ms_t
eAllowPosOverflow = 110,
eProfileParamSlot0_AllowableClosedLoopErr = 111,
eNumberPotTurns = 112,
eNumberEncoderCPR = 113,
ePwdPosition = 114,
eAinPosition = 115,
eProfileParamVcompRate = 116,
eProfileParamSlot1_AllowableClosedLoopErr = 117,
eStatus9FrameRate = 118, // TALON_Status_9_MotProfBuffer_100ms_t
eMotionProfileHasUnderrunErr = 119,
eReserved120 = 120,
eLegacyControlMode = 121,
};
//---- setters and getters that use the solicated param request/response ---//
/**
* Send a one shot frame to set an arbitrary signal.
* Most signals are in the control frame so avoid using this API unless you
* have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed
* up in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing
* this, use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so
* GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParam(param_t paramEnum, double value);
/**
* Asks TALON to immedietely respond with signal value. This API is only used
* for signals that are not sent periodically.
* This can be useful for reading params that rarely change like Limit Switch
* settings and PIDF values.
* @param param to request.
*/
CTR_Code RequestParam(param_t paramEnum);
CTR_Code GetParamResponse(param_t paramEnum, double &value);
CTR_Code GetParamResponseInt32(param_t paramEnum, int &value);
//----------- getters and setters that use param request/response ----------//
/**
* These signals are backed up in flash and will survive a power cycle.
* If your application requires changing these values consider using both
* slots and switch between slot0 <=> slot1.
* If your application requires changing these signals frequently then it
* makes sense to leverage this API.
* Getters don't block, so it may require several calls to get the latest
* value.
*/
CTR_Code SetPgain(unsigned slotIdx, double gain);
CTR_Code SetIgain(unsigned slotIdx, double gain);
CTR_Code SetDgain(unsigned slotIdx, double gain);
CTR_Code SetFgain(unsigned slotIdx, double gain);
CTR_Code SetIzone(unsigned slotIdx, int zone);
CTR_Code SetCloseLoopRampRate(unsigned slotIdx, int closeLoopRampRate);
CTR_Code SetVoltageCompensationRate(double voltagePerMs);
CTR_Code SetSensorPosition(int pos);
CTR_Code SetForwardSoftLimit(int forwardLimit);
CTR_Code SetReverseSoftLimit(int reverseLimit);
CTR_Code SetForwardSoftEnable(int enable);
CTR_Code SetReverseSoftEnable(int enable);
CTR_Code GetPgain(unsigned slotIdx, double &gain);
CTR_Code GetIgain(unsigned slotIdx, double &gain);
CTR_Code GetDgain(unsigned slotIdx, double &gain);
CTR_Code GetFgain(unsigned slotIdx, double &gain);
CTR_Code GetIzone(unsigned slotIdx, int &zone);
CTR_Code GetCloseLoopRampRate(unsigned slotIdx, int &closeLoopRampRate);
CTR_Code GetVoltageCompensationRate(double &voltagePerMs);
CTR_Code GetForwardSoftLimit(int &forwardLimit);
CTR_Code GetReverseSoftLimit(int &reverseLimit);
CTR_Code GetForwardSoftEnable(int &enable);
CTR_Code GetReverseSoftEnable(int &enable);
CTR_Code GetPulseWidthRiseToFallUs(int &param);
CTR_Code IsPulseWidthSensorPresent(int &param);
CTR_Code SetModeSelect(int modeSelect, int demand);
/**
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums
* for what's available.
*/
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
/**
* Clear all sticky faults in TALON.
*/
CTR_Code ClearStickyFaults();
/**
* Calling application can opt to speed up the handshaking between the robot
* API and the Talon to increase the
* download rate of the Talon's Motion Profile. Ideally the period should be
* no more than half the period
* of a trajectory point.
*/
void ChangeMotionControlFramePeriod(uint32_t periodMs);
/**
* Clear the buffered motion profile in both Talon RAM (bottom), and in the
* API (top).
*/
void ClearMotionProfileTrajectories();
/**
* Retrieve just the buffer count for the api-level (top) buffer.
* This routine performs no CAN or data structure lookups, so its fast and
* ideal if caller needs to quickly poll the progress of trajectory points
* being emptied into Talon's RAM. Otherwise just use GetMotionProfileStatus.
* @return number of trajectory points in the top buffer.
*/
uint32_t GetMotionProfileTopLevelBufferCount();
/**
* Retrieve just the buffer full for the api-level (top) buffer.
* This routine performs no CAN or data structure lookups, so its fast and
* ideal if caller needs to quickly poll. Otherwise just use
* GetMotionProfileStatus.
* @return number of trajectory points in the top buffer.
*/
bool IsMotionProfileTopLevelBufferFull();
/**
* Push another trajectory point into the top level buffer (which is emptied
* into the Talon's bottom buffer as room allows).
* @param targPos servo position in native Talon units (sensor units).
* @param targVel velocity to feed-forward in native Talon units (sensor
* units per 100ms).
* @param profileSlotSelect which slot to pull PIDF gains from. Currently
* supports 0 or 1.
* @param timeDurMs time in milliseconds of how long to apply this point.
* @param velOnly set to nonzero to signal Talon that only the feed-foward
* velocity should be used, i.e. do not perform PID on
* position. This is equivalent to setting PID gains to zero,
* but much more efficient and synchronized to MP.
* @param isLastPoint set to nonzero to signal Talon to keep processing this
* trajectory point, instead of jumping to the next one
* when timeDurMs expires. Otherwise MP executer will
* eventually see an empty buffer after the last point
* expires, causing it to assert the IsUnderRun flag.
* However this may be desired if calling application
* nevers wants to terminate the MP.
* @param zeroPos set to nonzero to signal Talon to "zero" the selected
* position sensor before executing this trajectory point.
* Typically the first point should have this set only thus
* allowing the remainder of the MP positions to be relative
* to zero.
* @return CTR_OKAY if trajectory point push ok. CTR_BufferFull if buffer is
* full due to kMotionProfileTopBufferCapacity.
*/
CTR_Code PushMotionProfileTrajectory(int targPos, int targVel,
int profileSlotSelect, int timeDurMs,
int velOnly, int isLastPoint,
int zeroPos);
/**
* This must be called periodically to funnel the trajectory points from the
* API's top level buffer to the Talon's bottom level buffer. Recommendation
* is to call this twice as fast as the executation rate of the motion
* profile. So if MP is running with 20ms trajectory points, try calling
* this routine every 10ms. All motion profile functions are thread-safe
* through the use of a mutex, so there is no harm in having the caller
* utilize threading.
*/
void ProcessMotionProfileBuffer();
/**
* Retrieve all status information.
* Since this all comes from one CAN frame, its ideal to have one routine to
* retrieve the frame once and decode everything.
* @param [out] flags bitfield for status bools. Starting with least
* significant bit: IsValid, HasUnderrun, IsUnderrun, IsLast, VelOnly.
*
* IsValid set when MP executer is processing a trajectory point,
* and that point's status is instrumented with IsLast,
* VelOnly, targPos, targVel. However if MP executor is
* not processing a trajectory point, then this flag is
* false, and the instrumented signals will be zero.
* HasUnderrun is set anytime the MP executer is ready to pop
* another trajectory point from the Talon's RAM,
* but the buffer is empty. It can only be cleared
* by using SetParam(eMotionProfileHasUnderrunErr,0);
* IsUnderrun is set when the MP executer is ready for another
* point, but the buffer is empty, and cleared when
* the MP executer does not need another point.
* HasUnderrun shadows this registor when this
* register gets set, however HasUnderrun stays
* asserted until application has process it, and
* IsUnderrun auto-clears when the condition is
* resolved.
* IsLast is set/cleared based on the MP executer's current
* trajectory point's IsLast value. This assumes
* IsLast was set when PushMotionProfileTrajectory
* was used to insert the currently processed trajectory
* point.
* VelOnly is set/cleared based on the MP executer's current
* trajectory point's VelOnly value.
*
* @param [out] profileSlotSelect The currently processed trajectory point's
* selected slot. This can differ in the currently selected slot used
* for Position and Velocity servo modes.
* @param [out] targPos The currently processed trajectory point's position
* in native units. This param is zero if IsValid is zero.
* @param [out] targVel The currently processed trajectory point's velocity
* in native units. This param is zero if IsValid is zero.
* @param [out] topBufferRem The remaining number of points in the top level
* buffer.
* @param [out] topBufferCnt The number of points in the top level buffer to
* be sent to Talon.
* @param [out] btmBufferCnt The number of points in the bottom level buffer
* inside Talon.
* @return CTR error code
*/
CTR_Code GetMotionProfileStatus(uint32_t &flags, uint32_t &profileSlotSelect,
int32_t &targPos, int32_t &targVel,
uint32_t &topBufferRemaining,
uint32_t &topBufferCnt,
uint32_t &btmBufferCnt,
uint32_t &outputEnable);
//------------------------ auto generated ------------------------------------//
/* This API is optimal since it uses the fire-and-forget CAN interface.
* These signals should cover the majority of all use cases.
*/
CTR_Code GetFault_OverTemp(int &param);
CTR_Code GetFault_UnderVoltage(int &param);
CTR_Code GetFault_ForLim(int &param);
CTR_Code GetFault_RevLim(int &param);
CTR_Code GetFault_HardwareFailure(int &param);
CTR_Code GetFault_ForSoftLim(int &param);
CTR_Code GetFault_RevSoftLim(int &param);
CTR_Code GetStckyFault_OverTemp(int &param);
CTR_Code GetStckyFault_UnderVoltage(int &param);
CTR_Code GetStckyFault_ForLim(int &param);
CTR_Code GetStckyFault_RevLim(int &param);
CTR_Code GetStckyFault_ForSoftLim(int &param);
CTR_Code GetStckyFault_RevSoftLim(int &param);
CTR_Code GetAppliedThrottle(int &param);
CTR_Code GetCloseLoopErr(int &param);
CTR_Code GetFeedbackDeviceSelect(int &param);
CTR_Code GetModeSelect(int &param);
CTR_Code GetLimitSwitchEn(int &param);
CTR_Code GetLimitSwitchClosedFor(int &param);
CTR_Code GetLimitSwitchClosedRev(int &param);
CTR_Code GetSensorPosition(int &param);
CTR_Code GetSensorVelocity(int &param);
CTR_Code GetCurrent(double &param);
CTR_Code GetBrakeIsEnabled(int &param);
CTR_Code GetEncPosition(int &param);
CTR_Code GetEncVel(int &param);
CTR_Code GetEncIndexRiseEvents(int &param);
CTR_Code GetQuadApin(int &param);
CTR_Code GetQuadBpin(int &param);
CTR_Code GetQuadIdxpin(int &param);
CTR_Code GetAnalogInWithOv(int &param);
CTR_Code GetAnalogInVel(int &param);
CTR_Code GetTemp(double &param);
CTR_Code GetBatteryV(double &param);
CTR_Code GetResetCount(int &param);
CTR_Code GetResetFlags(int &param);
CTR_Code GetFirmVers(int &param);
CTR_Code GetPulseWidthPosition(int &param);
CTR_Code GetPulseWidthVelocity(int &param);
CTR_Code GetPulseWidthRiseToRiseUs(int &param);
CTR_Code GetActTraj_IsValid(int &param);
CTR_Code GetActTraj_ProfileSlotSelect(int &param);
CTR_Code GetActTraj_VelOnly(int &param);
CTR_Code GetActTraj_IsLast(int &param);
CTR_Code GetOutputType(int &param);
CTR_Code GetHasUnderrun(int &param);
CTR_Code GetIsUnderrun(int &param);
CTR_Code GetNextID(int &param);
CTR_Code GetBufferIsFull(int &param);
CTR_Code GetCount(int &param);
CTR_Code GetActTraj_Velocity(int &param);
CTR_Code GetActTraj_Position(int &param);
CTR_Code SetDemand(int param);
CTR_Code SetOverrideLimitSwitchEn(int param);
CTR_Code SetFeedbackDeviceSelect(int param);
CTR_Code SetRevMotDuringCloseLoopEn(int param);
CTR_Code SetOverrideBrakeType(int param);
CTR_Code SetModeSelect(int param);
CTR_Code SetProfileSlotSelect(int param);
CTR_Code SetRampThrottle(int param);
CTR_Code SetRevFeedbackSensor(int param);
};
extern "C" {
void *c_TalonSRX_Create3(int deviceNumber, int controlPeriodMs, int enablePeriodMs);
void *c_TalonSRX_Create2(int deviceNumber, int controlPeriodMs);
void *c_TalonSRX_Create1(int deviceNumber);
void c_TalonSRX_Destroy(void *handle);
void c_TalonSRX_Set(void *handle, double value);
CTR_Code c_TalonSRX_SetParam(void *handle, int paramEnum, double value);
CTR_Code c_TalonSRX_RequestParam(void *handle, int paramEnum);
CTR_Code c_TalonSRX_GetParamResponse(void *handle, int paramEnum, double *value);
CTR_Code c_TalonSRX_GetParamResponseInt32(void *handle, int paramEnum, int *value);
CTR_Code c_TalonSRX_SetPgain(void *handle, int slotIdx, double gain);
CTR_Code c_TalonSRX_SetIgain(void *handle, int slotIdx, double gain);
CTR_Code c_TalonSRX_SetDgain(void *handle, int slotIdx, double gain);
CTR_Code c_TalonSRX_SetFgain(void *handle, int slotIdx, double gain);
CTR_Code c_TalonSRX_SetIzone(void *handle, int slotIdx, int zone);
CTR_Code c_TalonSRX_SetCloseLoopRampRate(void *handle, int slotIdx, int closeLoopRampRate);
CTR_Code c_TalonSRX_SetVoltageCompensationRate(void *handle, double voltagePerMs);
CTR_Code c_TalonSRX_SetSensorPosition(void *handle, int pos);
CTR_Code c_TalonSRX_SetForwardSoftLimit(void *handle, int forwardLimit);
CTR_Code c_TalonSRX_SetReverseSoftLimit(void *handle, int reverseLimit);
CTR_Code c_TalonSRX_SetForwardSoftEnable(void *handle, int enable);
CTR_Code c_TalonSRX_SetReverseSoftEnable(void *handle, int enable);
CTR_Code c_TalonSRX_GetPgain(void *handle, int slotIdx, double *gain);
CTR_Code c_TalonSRX_GetIgain(void *handle, int slotIdx, double *gain);
CTR_Code c_TalonSRX_GetDgain(void *handle, int slotIdx, double *gain);
CTR_Code c_TalonSRX_GetFgain(void *handle, int slotIdx, double *gain);
CTR_Code c_TalonSRX_GetIzone(void *handle, int slotIdx, int *zone);
CTR_Code c_TalonSRX_GetCloseLoopRampRate(void *handle, int slotIdx, int *closeLoopRampRate);
CTR_Code c_TalonSRX_GetVoltageCompensationRate(void *handle, double *voltagePerMs);
CTR_Code c_TalonSRX_GetForwardSoftLimit(void *handle, int *forwardLimit);
CTR_Code c_TalonSRX_GetReverseSoftLimit(void *handle, int *reverseLimit);
CTR_Code c_TalonSRX_GetForwardSoftEnable(void *handle, int *enable);
CTR_Code c_TalonSRX_GetReverseSoftEnable(void *handle, int *enable);
CTR_Code c_TalonSRX_GetPulseWidthRiseToFallUs(void *handle, int *param);
CTR_Code c_TalonSRX_IsPulseWidthSensorPresent(void *handle, int *param);
CTR_Code c_TalonSRX_SetModeSelect2(void *handle, int modeSelect, int demand);
CTR_Code c_TalonSRX_SetStatusFrameRate(void *handle, int frameEnum, int periodMs);
CTR_Code c_TalonSRX_ClearStickyFaults(void *handle);
void c_TalonSRX_ChangeMotionControlFramePeriod(void *handle, int periodMs);
void c_TalonSRX_ClearMotionProfileTrajectories(void *handle);
int c_TalonSRX_GetMotionProfileTopLevelBufferCount(void *handle);
int c_TalonSRX_IsMotionProfileTopLevelBufferFull(void *handle);
CTR_Code c_TalonSRX_PushMotionProfileTrajectory(void *handle, int targPos, int targVel, int profileSlotSelect, int timeDurMs, int velOnly, int isLastPoint, int zeroPos);
void c_TalonSRX_ProcessMotionProfileBuffer(void *handle);
CTR_Code c_TalonSRX_GetMotionProfileStatus(void *handle, int *flags, int *profileSlotSelect, int *targPos, int *targVel, int *topBufferRemaining, int *topBufferCnt, int *btmBufferCnt, int *outputEnable);
CTR_Code c_TalonSRX_GetFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_HardwareFailure(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetAppliedThrottle(void *handle, int *param);
CTR_Code c_TalonSRX_GetCloseLoopErr(void *handle, int *param);
CTR_Code c_TalonSRX_GetFeedbackDeviceSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetModeSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchEn(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedFor(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedRev(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorVelocity(void *handle, int *param);
CTR_Code c_TalonSRX_GetCurrent(void *handle, double *param);
CTR_Code c_TalonSRX_GetBrakeIsEnabled(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncIndexRiseEvents(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadApin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadBpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadIdxpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInWithOv(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetTemp(void *handle, double *param);
CTR_Code c_TalonSRX_GetBatteryV(void *handle, double *param);
CTR_Code c_TalonSRX_GetResetCount(void *handle, int *param);
CTR_Code c_TalonSRX_GetResetFlags(void *handle, int *param);
CTR_Code c_TalonSRX_GetFirmVers(void *handle, int *param);
CTR_Code c_TalonSRX_GetPulseWidthPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetPulseWidthVelocity(void *handle, int *param);
CTR_Code c_TalonSRX_GetPulseWidthRiseToRiseUs(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_IsValid(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_ProfileSlotSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_VelOnly(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_IsLast(void *handle, int *param);
CTR_Code c_TalonSRX_GetOutputType(void *handle, int *param);
CTR_Code c_TalonSRX_GetHasUnderrun(void *handle, int *param);
CTR_Code c_TalonSRX_GetIsUnderrun(void *handle, int *param);
CTR_Code c_TalonSRX_GetNextID(void *handle, int *param);
CTR_Code c_TalonSRX_GetBufferIsFull(void *handle, int *param);
CTR_Code c_TalonSRX_GetCount(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_Velocity(void *handle, int *param);
CTR_Code c_TalonSRX_GetActTraj_Position(void *handle, int *param);
CTR_Code c_TalonSRX_SetDemand(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideLimitSwitchEn(void *handle, int param);
CTR_Code c_TalonSRX_SetFeedbackDeviceSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRevMotDuringCloseLoopEn(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideBrakeType(void *handle, int param);
CTR_Code c_TalonSRX_SetModeSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetProfileSlotSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRampThrottle(void *handle, int param);
CTR_Code c_TalonSRX_SetRevFeedbackSensor(void *handle, int param);
}
#endif

View File

@@ -1,33 +0,0 @@
/**
* Compressor.h
* Methods for interacting with a compressor with the CAN PCM device
*/
#include <stdint.h>
#ifndef __HAL_COMPRESSOR_H__
#define __HAL_COMPRESSOR_H__
extern "C" {
void *initializeCompressor(uint8_t module);
bool checkCompressorModule(uint8_t module);
bool getCompressor(void *pcm_pointer, int32_t *status);
void setClosedLoopControl(void *pcm_pointer, bool value, int32_t *status);
bool getClosedLoopControl(void *pcm_pointer, int32_t *status);
bool getPressureSwitch(void *pcm_pointer, int32_t *status);
float getCompressorCurrent(void *pcm_pointer, int32_t *status);
bool getCompressorCurrentTooHighFault(void *pcm_pointer, int32_t *status);
bool getCompressorCurrentTooHighStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorShortedStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorShortedFault(void *pcm_pointer, int32_t *status);
bool getCompressorNotConnectedStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorNotConnectedFault(void *pcm_pointer, int32_t *status);
void clearAllPCMStickyFaults(void *pcm_pointer, int32_t *status);
}
#endif

View File

@@ -1,139 +0,0 @@
#pragma once
#include <stdint.h>
#include "HAL/cpp/priority_mutex.h"
enum Mode
{
kTwoPulse = 0,
kSemiperiod = 1,
kPulseLength = 2,
kExternalDirection = 3
};
priority_recursive_mutex& spiGetSemaphore(uint8_t port);
extern "C"
{
void* initializeDigitalPort(void* port_pointer, int32_t *status);
void freeDigitalPort(void* digital_port_pointer);
bool checkPWMChannel(void* digital_port_pointer);
bool checkRelayChannel(void* digital_port_pointer);
void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status);
bool allocatePWMChannel(void* digital_port_pointer, int32_t *status);
void freePWMChannel(void* digital_port_pointer, int32_t *status);
unsigned short getPWM(void* digital_port_pointer, int32_t *status);
void latchPWMZero(void* digital_port_pointer, int32_t *status);
void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask, int32_t *status);
void* allocatePWM(int32_t *status);
void freePWM(void* pwmGenerator, int32_t *status);
void setPWMRate(double rate, int32_t *status);
void setPWMDutyCycle(void* pwmGenerator, double dutyCycle, int32_t *status);
void setPWMOutputChannel(void* pwmGenerator, uint32_t pin, int32_t *status);
void setRelayForward(void* digital_port_pointer, bool on, int32_t *status);
void setRelayReverse(void* digital_port_pointer, bool on, int32_t *status);
bool getRelayForward(void* digital_port_pointer, int32_t *status);
bool getRelayReverse(void* digital_port_pointer, int32_t *status);
bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status);
void freeDIO(void* digital_port_pointer, int32_t *status);
void setDIO(void* digital_port_pointer, short value, int32_t *status);
bool getDIO(void* digital_port_pointer, int32_t *status);
bool getDIODirection(void* digital_port_pointer, int32_t *status);
void pulse(void* digital_port_pointer, double pulseLength, int32_t *status);
bool isPulsing(void* digital_port_pointer, int32_t *status);
bool isAnyPulsing(int32_t *status);
void setFilterSelect(void* digital_port_pointer, int filter_index,
int32_t* status);
int getFilterSelect(void* digital_port_pointer, int32_t* status);
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status);
uint32_t getFilterPeriod(int filter_index, int32_t* status);
void* initializeCounter(Mode mode, uint32_t *index, int32_t *status);
void freeCounter(void* counter_pointer, int32_t *status);
void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status);
void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
void clearCounterUpSource(void* counter_pointer, int32_t *status);
void setCounterDownSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
void clearCounterDownSource(void* counter_pointer, int32_t *status);
void setCounterUpDownMode(void* counter_pointer, int32_t *status);
void setCounterExternalDirectionMode(void* counter_pointer, int32_t *status);
void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod, int32_t *status);
void setCounterPulseLengthMode(void* counter_pointer, double threshold, int32_t *status);
int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t *status);
void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage, int32_t *status);
void resetCounter(void* counter_pointer, int32_t *status);
int32_t getCounter(void* counter_pointer, int32_t *status);
double getCounterPeriod(void* counter_pointer, int32_t *status);
void setCounterMaxPeriod(void* counter_pointer, double maxPeriod, int32_t *status);
void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled, int32_t *status);
bool getCounterStopped(void* counter_pointer, int32_t *status);
bool getCounterDirection(void* counter_pointer, int32_t *status);
void setCounterReverseDirection(void* counter_pointer, bool reverseDirection, int32_t *status);
void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_analog_trigger,
uint8_t port_b_module, uint32_t port_b_pin, bool port_b_analog_trigger,
bool reverseDirection, int32_t *index, int32_t *status); // TODO: fix routing
void freeEncoder(void* encoder_pointer, int32_t *status);
void resetEncoder(void* encoder_pointer, int32_t *status);
int32_t getEncoder(void* encoder_pointer, int32_t *status); // Raw value
double getEncoderPeriod(void* encoder_pointer, int32_t *status);
void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod, int32_t *status);
bool getEncoderStopped(void* encoder_pointer, int32_t *status);
bool getEncoderDirection(void* encoder_pointer, int32_t *status);
void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection, int32_t *status);
void setEncoderSamplesToAverage(void* encoder_pointer, uint32_t samplesToAverage,
int32_t *status);
uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t *status);
void setEncoderIndexSource(void *encoder_pointer, uint32_t pin, bool analogTrigger, bool activeHigh,
bool edgeSensitive, int32_t *status);
uint16_t getLoopTiming(int32_t *status);
void spiInitialize(uint8_t port, int32_t *status);
int32_t spiTransaction(uint8_t port, uint8_t *dataToSend, uint8_t *dataReceived, uint8_t size);
int32_t spiWrite(uint8_t port, uint8_t* dataToSend, uint8_t sendSize);
int32_t spiRead(uint8_t port, uint8_t *buffer, uint8_t count);
void spiClose(uint8_t port);
void spiSetSpeed(uint8_t port, uint32_t speed);
void spiSetOpts(uint8_t port, int msb_first, int sample_on_trailing, int clk_idle_high);
void spiSetChipSelectActiveHigh(uint8_t port, int32_t *status);
void spiSetChipSelectActiveLow(uint8_t port, int32_t *status);
int32_t spiGetHandle(uint8_t port);
void spiSetHandle(uint8_t port, int32_t handle);
void spiInitAccumulator(uint8_t port, uint32_t period, uint32_t cmd,
uint8_t xfer_size, uint32_t valid_mask,
uint32_t valid_value, uint8_t data_shift,
uint8_t data_size, bool is_signed, bool big_endian,
int32_t *status);
void spiFreeAccumulator(uint8_t port, int32_t *status);
void spiResetAccumulator(uint8_t port, int32_t *status);
void spiSetAccumulatorCenter(uint8_t port, int32_t center, int32_t *status);
void spiSetAccumulatorDeadband(uint8_t port, int32_t deadband, int32_t *status);
int32_t spiGetAccumulatorLastValue(uint8_t port, int32_t *status);
int64_t spiGetAccumulatorValue(uint8_t port, int32_t *status);
uint32_t spiGetAccumulatorCount(uint8_t port, int32_t *status);
double spiGetAccumulatorAverage(uint8_t port, int32_t *status);
void spiGetAccumulatorOutput(uint8_t port, int64_t *value, uint32_t *count,
int32_t *status);
void i2CInitialize(uint8_t port, int32_t *status);
int32_t i2CTransaction(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize);
int32_t i2CWrite(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize);
int32_t i2CRead(uint8_t port, uint8_t deviceAddress, uint8_t *buffer, uint8_t count);
void i2CClose(uint8_t port);
//// Float JNA Hack
// double
void setPWMRateIntHack(int rate, int32_t *status);
void setPWMDutyCycleIntHack(void* pwmGenerator, int32_t dutyCycle, int32_t *status);
}

View File

@@ -1,64 +0,0 @@
#pragma once
#define CTR_RxTimeout_MESSAGE "CTRE CAN Recieve Timeout"
#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)"
#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
#define NiFpga_Status_MemoryFull_MESSAGE "NIFPGA: Memory Allocation failed, memory full"
#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexepected software error"
#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter"
#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found"
#define NiFpga_Status_ResourceNotInitialized_MESSAGE "NIFPGA: Resource not initialized"
#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault"
#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout"
#define ERR_CANSessionMux_InvalidBuffer_MESSAGE "CAN: Invalid Buffer"
#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found"
#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token"
#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed"
#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized"
#define SAMPLE_RATE_TOO_HIGH 1001
#define SAMPLE_RATE_TOO_HIGH_MESSAGE "HAL: Analog module sample rate is too high"
#define VOLTAGE_OUT_OF_RANGE 1002
#define VOLTAGE_OUT_OF_RANGE_MESSAGE "HAL: Voltage to convert to raw value is out of range [0; 5]"
#define LOOP_TIMING_ERROR 1004
#define LOOP_TIMING_ERROR_MESSAGE "HAL: Digital module loop timing is not the expected value"
#define SPI_WRITE_NO_MOSI 1012
#define SPI_WRITE_NO_MOSI_MESSAGE "HAL: Cannot write to SPI port with no MOSI output"
#define SPI_READ_NO_MISO 1013
#define SPI_READ_NO_MISO_MESSAGE "HAL: Cannot read from SPI port with no MISO input"
#define SPI_READ_NO_DATA 1014
#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI"
#define INCOMPATIBLE_STATE 1015
#define INCOMPATIBLE_STATE_MESSAGE "HAL: Incompatible State: The operation cannot be completed"
#define NO_AVAILABLE_RESOURCES -1004
#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate"
#define NULL_PARAMETER -1005
#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL"
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "HAL: AnalogTrigger limits error. Lower limit > Upper Limit"
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output."
#define PARAMETER_OUT_OF_RANGE -1028
#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
#define RESOURCE_IS_ALLOCATED -1029
#define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated"
#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"
#define VI_ERROR_RSRC_NFOUND_MESSAGE "HAL - VISA: Resource Not Found"
#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"
#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow"
#define VI_ERROR_IO_MESSAGE "HAL - VISA: General IO Error"
#define VI_ERROR_ASRL_PARITY_MESSAGE "HAL - VISA: Parity Error"
#define VI_ERROR_ASRL_FRAMING_MESSAGE "HAL - VISA: Framing Error"
#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error"
#define VI_ERROR_RSRC_BUSY_MESSAGE "HAL - VISA: Resource Busy"
#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter"

View File

@@ -1,271 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2013. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <stdint.h>
#include <cmath>
#include "Accelerometer.hpp"
#include "Analog.hpp"
#include "Compressor.hpp"
#include "Digital.hpp"
#include "Solenoid.hpp"
#include "Notifier.hpp"
#include "Interrupts.hpp"
#include "Errors.hpp"
#include "PDP.hpp"
#include "Power.hpp"
#include "SerialPort.hpp"
#include "Utilities.hpp"
#include "Semaphore.hpp"
#include "Task.hpp"
#define HAL_IO_CONFIG_DATA_SIZE 32
#define HAL_SYS_STATUS_DATA_SIZE 44
#define HAL_USER_STATUS_DATA_SIZE (984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Input 17
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Output 18
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Header 19
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra1 20
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices1 21
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra2 22
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices2 23
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Joystick 24
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Custom 25
namespace HALUsageReporting
{
enum tResourceType
{
kResourceType_Controller,
kResourceType_Module,
kResourceType_Language,
kResourceType_CANPlugin,
kResourceType_Accelerometer,
kResourceType_ADXL345,
kResourceType_AnalogChannel,
kResourceType_AnalogTrigger,
kResourceType_AnalogTriggerOutput,
kResourceType_CANJaguar,
kResourceType_Compressor,
kResourceType_Counter,
kResourceType_Dashboard,
kResourceType_DigitalInput,
kResourceType_DigitalOutput,
kResourceType_DriverStationCIO,
kResourceType_DriverStationEIO,
kResourceType_DriverStationLCD,
kResourceType_Encoder,
kResourceType_GearTooth,
kResourceType_Gyro,
kResourceType_I2C,
kResourceType_Framework,
kResourceType_Jaguar,
kResourceType_Joystick,
kResourceType_Kinect,
kResourceType_KinectStick,
kResourceType_PIDController,
kResourceType_Preferences,
kResourceType_PWM,
kResourceType_Relay,
kResourceType_RobotDrive,
kResourceType_SerialPort,
kResourceType_Servo,
kResourceType_Solenoid,
kResourceType_SPI,
kResourceType_Task,
kResourceType_Ultrasonic,
kResourceType_Victor,
kResourceType_Button,
kResourceType_Command,
kResourceType_AxisCamera,
kResourceType_PCVideoServer,
kResourceType_SmartDashboard,
kResourceType_Talon,
kResourceType_HiTechnicColorSensor,
kResourceType_HiTechnicAccel,
kResourceType_HiTechnicCompass,
kResourceType_SRF08,
kResourceType_AnalogOutput,
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_ADXL362,
kResourceType_ADXRS450,
kResourceType_RevSPARK,
kResourceType_MindsensorsSD540,
kResourceType_DigitalFilter,
};
enum tInstances
{
kLanguage_LabVIEW = 1,
kLanguage_CPlusPlus = 2,
kLanguage_Java = 3,
kLanguage_Python = 4,
kCANPlugin_BlackJagBridge = 1,
kCANPlugin_2CAN = 2,
kFramework_Iterative = 1,
kFramework_Sample = 2,
kFramework_CommandControl = 3,
kRobotDrive_ArcadeStandard = 1,
kRobotDrive_ArcadeButtonSpin = 2,
kRobotDrive_ArcadeRatioCurve = 3,
kRobotDrive_Tank = 4,
kRobotDrive_MecanumPolar = 5,
kRobotDrive_MecanumCartesian = 6,
kDriverStationCIO_Analog = 1,
kDriverStationCIO_DigitalIn = 2,
kDriverStationCIO_DigitalOut = 3,
kDriverStationEIO_Acceleration = 1,
kDriverStationEIO_AnalogIn = 2,
kDriverStationEIO_AnalogOut = 3,
kDriverStationEIO_Button = 4,
kDriverStationEIO_LED = 5,
kDriverStationEIO_DigitalIn = 6,
kDriverStationEIO_DigitalOut = 7,
kDriverStationEIO_FixedDigitalOut = 8,
kDriverStationEIO_PWM = 9,
kDriverStationEIO_Encoder = 10,
kDriverStationEIO_TouchSlider = 11,
kADXL345_SPI = 1,
kADXL345_I2C = 2,
kCommand_Scheduler = 1,
kSmartDashboard_Instance = 1,
};
}
struct HALControlWord {
uint32_t enabled : 1;
uint32_t autonomous : 1;
uint32_t test :1;
uint32_t eStop : 1;
uint32_t fmsAttached:1;
uint32_t dsAttached:1;
uint32_t control_reserved : 26;
};
enum HALAllianceStationID {
kHALAllianceStationID_red1,
kHALAllianceStationID_red2,
kHALAllianceStationID_red3,
kHALAllianceStationID_blue1,
kHALAllianceStationID_blue2,
kHALAllianceStationID_blue3,
};
/* The maximum number of axes that will be stored in a single HALJoystickAxes
struct. This is used for allocating buffers, not bounds checking, since
there are usually less axes in practice. */
static const size_t kMaxJoystickAxes = 12;
static const size_t kMaxJoystickPOVs = 12;
struct HALJoystickAxes {
uint16_t count;
int16_t axes[kMaxJoystickAxes];
};
struct HALJoystickPOVs {
uint16_t count;
int16_t povs[kMaxJoystickPOVs];
};
struct HALJoystickButtons {
uint32_t buttons;
uint8_t count;
};
struct HALJoystickDescriptor {
uint8_t isXbox;
uint8_t type;
char name[256];
uint8_t axisCount;
uint8_t axisTypes[kMaxJoystickAxes];
uint8_t buttonCount;
uint8_t povCount;
};
inline float intToFloat(int value)
{
return (float)value;
}
inline int floatToInt(float value)
{
return round(value);
}
extern "C"
{
extern const uint32_t dio_kNumSystems;
extern const uint32_t solenoid_kNumDO7_0Elements;
extern const uint32_t interrupt_kNumSystems;
extern const uint32_t kSystemClockTicksPerMicrosecond;
void* getPort(uint8_t pin);
void* getPortWithModule(uint8_t module, uint8_t pin);
void freePort(void* port);
const char* getHALErrorMessage(int32_t code);
uint16_t getFPGAVersion(int32_t *status);
uint32_t getFPGARevision(int32_t *status);
uint64_t getFPGATime(int32_t *status);
bool getFPGAButton(int32_t *status);
int HALSetErrorData(const char *errors, int errorsLength, int wait_ms);
int HALSendError(int isError, int32_t errorCode, int isLVCode,
const char *details, const char *location, const char *callStack,
int printMsg);
int HALGetControlWord(HALControlWord *data);
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
int HALGetJoystickIsXbox(uint8_t joystickNum);
int HALGetJoystickType(uint8_t joystickNum);
char* HALGetJoystickName(uint8_t joystickNum);
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis);
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
int HALGetMatchTime(float *matchTime);
void HALSetNewDataSem(MULTIWAIT_ID sem);
bool HALGetSystemActive(int32_t *status);
bool HALGetBrownedOut(int32_t *status);
int HALInitialize(int mode = 0);
void HALNetworkCommunicationObserveUserProgramStarting();
void HALNetworkCommunicationObserveUserProgramDisabled();
void HALNetworkCommunicationObserveUserProgramAutonomous();
void HALNetworkCommunicationObserveUserProgramTeleop();
void HALNetworkCommunicationObserveUserProgramTest();
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context = 0,
const char *feature = NULL);
}
// TODO: HACKS for now...
extern "C"
{
void NumericArrayResize();
void RTSetCleanupProc();
void EDVR_CreateReference();
void Occur();
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <stdint.h>
#include <iostream>
#include "errno.h"
extern "C"
{
typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void *param);
void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status);
void cleanInterrupts(void* interrupt_pointer, int32_t *status);
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status);
void enableInterrupts(void* interrupt_pointer, int32_t *status);
void disableInterrupts(void* interrupt_pointer, int32_t *status);
double readRisingTimestamp(void* interrupt_pointer, int32_t *status);
double readFallingTimestamp(void* interrupt_pointer, int32_t *status);
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
bool routing_analog_trigger, int32_t *status);
void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler,
void* param, int32_t *status);
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
}

View File

@@ -1,12 +0,0 @@
#pragma once
#include <stdint.h>
extern "C"
{
void* initializeNotifier(void (*process)(uint64_t, void*), void* param, int32_t *status);
void cleanNotifier(void* notifier_pointer, int32_t *status);
void* getNotifierParam(void* notifier_pointer, int32_t *status);
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime, int32_t *status);
void stopNotifierAlarm(void* notifier_pointer, int32_t *status);
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <stdint.h>
extern "C"
{
void initializePDP(uint8_t module);
double getPDPTemperature(uint8_t module, int32_t *status);
double getPDPVoltage(uint8_t module, int32_t *status);
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t *status);
double getPDPTotalCurrent(uint8_t module, int32_t *status);
double getPDPTotalPower(uint8_t module, int32_t *status);
double getPDPTotalEnergy(uint8_t module, int32_t *status);
void resetPDPTotalEnergy(uint8_t module, int32_t *status);
void clearPDPStickyFaults(uint8_t module, int32_t *status);
}

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