Commit bb4a1410 authored by Kyle Edwards's avatar Kyle Edwards Committed by Brad King
Browse files

CTest: Add lexer for PROCESSES property

parent a1f78a48
......@@ -922,6 +922,7 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestMemCheckCommand.cxx
CTest/cmCTestMemCheckHandler.cxx
CTest/cmCTestMultiProcessHandler.cxx
CTest/cmCTestProcessesLexerHelper.cxx
CTest/cmCTestReadCustomFilesCommand.cxx
CTest/cmCTestRunScriptCommand.cxx
CTest/cmCTestRunTest.cxx
......@@ -953,6 +954,10 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestHG.h
CTest/cmCTestP4.cxx
CTest/cmCTestP4.h
LexerParser/cmCTestProcessesLexer.cxx
LexerParser/cmCTestProcessesLexer.h
LexerParser/cmCTestProcessesLexer.in.l
)
# Build CTestLib
......
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestProcessesLexerHelper.h"
#include "cmCTestProcessesLexer.h"
#include "cmCTestTestHandler.h"
cmCTestProcessesLexerHelper::cmCTestProcessesLexerHelper(
std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
output)
: Output(output)
{
}
bool cmCTestProcessesLexerHelper::ParseString(const std::string& value)
{
yyscan_t lexer;
cmCTestProcesses_yylex_init_extra(this, &lexer);
auto state = cmCTestProcesses_yy_scan_string(value.c_str(), lexer);
int retval = cmCTestProcesses_yylex(lexer);
cmCTestProcesses_yy_delete_buffer(state, lexer);
cmCTestProcesses_yylex_destroy(lexer);
return retval == 0;
}
void cmCTestProcessesLexerHelper::SetProcessCount(unsigned int count)
{
this->ProcessCount = count;
}
void cmCTestProcessesLexerHelper::SetResourceType(const std::string& type)
{
this->ResourceType = type;
}
void cmCTestProcessesLexerHelper::SetNeededSlots(int count)
{
this->NeededSlots = count;
}
void cmCTestProcessesLexerHelper::WriteRequirement()
{
this->Process.push_back({ this->ResourceType, this->NeededSlots, 1 });
}
void cmCTestProcessesLexerHelper::WriteProcess()
{
for (unsigned int i = 0; i < this->ProcessCount; ++i) {
this->Output.push_back(this->Process);
}
this->Process.clear();
this->ProcessCount = 1;
}
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmCTestProcessesLexerHelper_h
#define cmCTestProcessesLexerHelper_h
#include <string>
#include <vector>
#include "cmCTestTestHandler.h"
class cmCTestProcessesLexerHelper
{
public:
struct ParserType
{
};
cmCTestProcessesLexerHelper(
std::vector<
std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
output);
~cmCTestProcessesLexerHelper() = default;
bool ParseString(const std::string& value);
void SetProcessCount(unsigned int count);
void SetResourceType(const std::string& type);
void SetNeededSlots(int count);
void WriteRequirement();
void WriteProcess();
private:
std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
Output;
unsigned int ProcessCount = 1;
std::string ResourceType;
int NeededSlots;
std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement> Process;
};
#define YY_EXTRA_TYPE cmCTestProcessesLexerHelper*
#endif
......@@ -29,6 +29,7 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestProcessesLexerHelper.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
......@@ -1610,6 +1611,14 @@ std::string cmCTestTestHandler::FindExecutable(
return fullPath;
}
bool cmCTestTestHandler::ParseProcessesProperty(
const std::string& val,
std::vector<std::vector<cmCTestTestResourceRequirement>>& processes)
{
cmCTestProcessesLexerHelper lexer(processes);
return lexer.ParseString(val);
}
void cmCTestTestHandler::GetListOfTests()
{
if (!this->IncludeLabelRegExp.empty()) {
......@@ -2179,6 +2188,11 @@ bool cmCTestTestHandler::SetTestsProperties(
if (key == "PROCESSOR_AFFINITY") {
rt.WantAffinity = cmIsOn(val);
}
if (key == "PROCESSES") {
if (!ParseProcessesProperty(val, rt.Processes)) {
return false;
}
}
if (key == "SKIP_RETURN_CODE") {
rt.SkipReturnCode = atoi(val.c_str());
if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
......@@ -2356,3 +2370,17 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
this->TestList.push_back(test);
return true;
}
bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator==(
const cmCTestTestResourceRequirement& other) const
{
return this->ResourceType == other.ResourceType &&
this->SlotsNeeded == other.SlotsNeeded &&
this->UnitsNeeded == other.UnitsNeeded;
}
bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator!=(
const cmCTestTestResourceRequirement& other) const
{
return !(*this == other);
}
......@@ -102,6 +102,16 @@ public:
void Initialize() override;
struct cmCTestTestResourceRequirement
{
std::string ResourceType;
int SlotsNeeded;
int UnitsNeeded;
bool operator==(const cmCTestTestResourceRequirement& other) const;
bool operator!=(const cmCTestTestResourceRequirement& other) const;
};
// NOTE: This struct is Saved/Restored
// in cmCTestTestHandler, if you add to this class
// then you must add the new members to that code or
......@@ -147,6 +157,7 @@ public:
std::set<std::string> FixturesCleanup;
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
std::vector<std::vector<cmCTestTestResourceRequirement>> Processes;
// Private test generator properties used to track backtraces
cmListFileBacktrace Backtrace;
};
......@@ -190,6 +201,10 @@ public:
std::vector<std::string>& extraPaths,
std::vector<std::string>& failed);
static bool ParseProcessesProperty(
const std::string& val,
std::vector<std::vector<cmCTestTestResourceRequirement>>& processes);
using ListOfTests = std::vector<cmCTestTestProperties>;
protected:
......
......@@ -2,6 +2,8 @@
/cmCommandArgumentLexer.h generated
/cmCommandArgumentParser.cxx generated
/cmCommandArgumentParserTokens.h generated
/cmCTestProcessesLexer.cxx generated
/cmCTestProcessesLexer.h generated
/cmDependsJavaLexer.cxx generated
/cmDependsJavaLexer.h generated
/cmDependsJavaParser.cxx generated
......
This diff is collapsed.
#ifndef cmCTestProcesses_yyHEADER_H
#define cmCTestProcesses_yyHEADER_H 1
#define cmCTestProcesses_yyIN_HEADER 1
#define FLEXINT_H 1
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
#ifdef yy_create_buffer
#define cmCTestProcesses_yy_create_buffer_ALREADY_DEFINED
#else
#define yy_create_buffer cmCTestProcesses_yy_create_buffer
#endif
#ifdef yy_delete_buffer
#define cmCTestProcesses_yy_delete_buffer_ALREADY_DEFINED
#else
#define yy_delete_buffer cmCTestProcesses_yy_delete_buffer
#endif
#ifdef yy_scan_buffer
#define cmCTestProcesses_yy_scan_buffer_ALREADY_DEFINED
#else
#define yy_scan_buffer cmCTestProcesses_yy_scan_buffer
#endif
#ifdef yy_scan_string
#define cmCTestProcesses_yy_scan_string_ALREADY_DEFINED
#else
#define yy_scan_string cmCTestProcesses_yy_scan_string
#endif
#ifdef yy_scan_bytes
#define cmCTestProcesses_yy_scan_bytes_ALREADY_DEFINED
#else
#define yy_scan_bytes cmCTestProcesses_yy_scan_bytes
#endif
#ifdef yy_init_buffer
#define cmCTestProcesses_yy_init_buffer_ALREADY_DEFINED
#else
#define yy_init_buffer cmCTestProcesses_yy_init_buffer
#endif
#ifdef yy_flush_buffer
#define cmCTestProcesses_yy_flush_buffer_ALREADY_DEFINED
#else
#define yy_flush_buffer cmCTestProcesses_yy_flush_buffer
#endif
#ifdef yy_load_buffer_state
#define cmCTestProcesses_yy_load_buffer_state_ALREADY_DEFINED
#else
#define yy_load_buffer_state cmCTestProcesses_yy_load_buffer_state
#endif
#ifdef yy_switch_to_buffer
#define cmCTestProcesses_yy_switch_to_buffer_ALREADY_DEFINED
#else
#define yy_switch_to_buffer cmCTestProcesses_yy_switch_to_buffer
#endif
#ifdef yypush_buffer_state
#define cmCTestProcesses_yypush_buffer_state_ALREADY_DEFINED
#else
#define yypush_buffer_state cmCTestProcesses_yypush_buffer_state
#endif
#ifdef yypop_buffer_state
#define cmCTestProcesses_yypop_buffer_state_ALREADY_DEFINED
#else
#define yypop_buffer_state cmCTestProcesses_yypop_buffer_state
#endif
#ifdef yyensure_buffer_stack
#define cmCTestProcesses_yyensure_buffer_stack_ALREADY_DEFINED
#else
#define yyensure_buffer_stack cmCTestProcesses_yyensure_buffer_stack
#endif
#ifdef yylex
#define cmCTestProcesses_yylex_ALREADY_DEFINED
#else
#define yylex cmCTestProcesses_yylex
#endif
#ifdef yyrestart
#define cmCTestProcesses_yyrestart_ALREADY_DEFINED
#else
#define yyrestart cmCTestProcesses_yyrestart
#endif
#ifdef yylex_init
#define cmCTestProcesses_yylex_init_ALREADY_DEFINED
#else
#define yylex_init cmCTestProcesses_yylex_init
#endif
#ifdef yylex_init_extra
#define cmCTestProcesses_yylex_init_extra_ALREADY_DEFINED
#else
#define yylex_init_extra cmCTestProcesses_yylex_init_extra
#endif
#ifdef yylex_destroy
#define cmCTestProcesses_yylex_destroy_ALREADY_DEFINED
#else
#define yylex_destroy cmCTestProcesses_yylex_destroy
#endif
#ifdef yyget_debug
#define cmCTestProcesses_yyget_debug_ALREADY_DEFINED
#else
#define yyget_debug cmCTestProcesses_yyget_debug
#endif
#ifdef yyset_debug
#define cmCTestProcesses_yyset_debug_ALREADY_DEFINED
#else
#define yyset_debug cmCTestProcesses_yyset_debug
#endif
#ifdef yyget_extra
#define cmCTestProcesses_yyget_extra_ALREADY_DEFINED
#else
#define yyget_extra cmCTestProcesses_yyget_extra
#endif
#ifdef yyset_extra
#define cmCTestProcesses_yyset_extra_ALREADY_DEFINED
#else
#define yyset_extra cmCTestProcesses_yyset_extra
#endif
#ifdef yyget_in
#define cmCTestProcesses_yyget_in_ALREADY_DEFINED
#else
#define yyget_in cmCTestProcesses_yyget_in
#endif
#ifdef yyset_in
#define cmCTestProcesses_yyset_in_ALREADY_DEFINED
#else
#define yyset_in cmCTestProcesses_yyset_in
#endif
#ifdef yyget_out
#define cmCTestProcesses_yyget_out_ALREADY_DEFINED
#else
#define yyget_out cmCTestProcesses_yyget_out
#endif
#ifdef yyset_out
#define cmCTestProcesses_yyset_out_ALREADY_DEFINED
#else
#define yyset_out cmCTestProcesses_yyset_out
#endif
#ifdef yyget_leng
#define cmCTestProcesses_yyget_leng_ALREADY_DEFINED
#else
#define yyget_leng cmCTestProcesses_yyget_leng
#endif
#ifdef yyget_text
#define cmCTestProcesses_yyget_text_ALREADY_DEFINED
#else
#define yyget_text cmCTestProcesses_yyget_text
#endif
#ifdef yyget_lineno
#define cmCTestProcesses_yyget_lineno_ALREADY_DEFINED
#else
#define yyget_lineno cmCTestProcesses_yyget_lineno
#endif
#ifdef yyset_lineno
#define cmCTestProcesses_yyset_lineno_ALREADY_DEFINED
#else
#define yyset_lineno cmCTestProcesses_yyset_lineno
#endif
#ifdef yyget_column
#define cmCTestProcesses_yyget_column_ALREADY_DEFINED
#else
#define yyget_column cmCTestProcesses_yyget_column
#endif
#ifdef yyset_column
#define cmCTestProcesses_yyset_column_ALREADY_DEFINED
#else
#define yyset_column cmCTestProcesses_yyset_column
#endif
#ifdef yywrap
#define cmCTestProcesses_yywrap_ALREADY_DEFINED
#else
#define yywrap cmCTestProcesses_yywrap
#endif
#ifdef yyalloc
#define cmCTestProcesses_yyalloc_ALREADY_DEFINED
#else
#define yyalloc cmCTestProcesses_yyalloc
#endif
#ifdef yyrealloc
#define cmCTestProcesses_yyrealloc_ALREADY_DEFINED
#else
#define yyrealloc cmCTestProcesses_yyrealloc
#endif
#ifdef yyfree
#define cmCTestProcesses_yyfree_ALREADY_DEFINED
#else
#define yyfree cmCTestProcesses_yyfree
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
/* flex integer type definitions */
#ifndef FLEXINT_H
#define FLEXINT_H
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#ifndef SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
/* begin standard C++ headers. */
/* TODO: this is always defined, so inline it */
#define yyconst const
#if defined(__GNUC__) && __GNUC__ >= 3
#define yynoreturn __attribute__((__noreturn__))
#else
#define yynoreturn
#endif
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
#define yyout yyg->yyout_r
#define yyextra yyg->yyextra_r
#define yyleng yyg->yyleng_r
#define yytext yyg->yytext_r
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;