Yzena
/
Yc
2
1
Fork 0
Browse Source

Add a separate main() function for all programs

Signed-off-by: Gavin Howard <gavin@yzena.com>
afl_persistent_mode
Gavin Howard 3 months ago
parent
commit
aea3e5438c
Signed by: gavin
GPG Key ID: C08038BDF280D33E
  1. 1
      CMakeLists.txt
  2. 13
      build.rig
  3. 1
      src/CMakeLists.txt
  4. 126
      src/main.c
  5. 115
      src/main.h
  6. 59
      src/rig/main.c
  7. 22
      src/rig/rig.h

1
CMakeLists.txt

@ -92,6 +92,7 @@ if(NOT "${MSVC}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-c++98-compat")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-disabled-macro-expansion")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-switch-enum")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-declaration-after-statement")
endif()
endif()

13
build.rig

@ -59,11 +59,11 @@
* ******** END FILE DESCRIPTION ********
*/
target #all: "libyc.a", "src/rig/main.o", "src/rig/rig.o", "src/rig/db.o",
"src/rig/target.o", "src/rig/build.o"
target #all: "libyc.a", "src/main.o", "src/rig/main.o", "src/rig/rig.o",
"src/rig/db.o", "src/rig/target.o", "src/rig/build.o"
{
$ clang -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_DARWIN_C_SOURCE
-Iinclude/ -o rig src/rig/main.o src/rig/rig.o src/rig/db.o
-Iinclude/ -o rig src/main.o src/rig/main.o src/rig/rig.o src/rig/db.o
src/rig/target.o src/rig/build.o libyc.a -lpthread;
$ ln -sf ./rig rigc;
}
@ -73,6 +73,13 @@ target #clean
$ rm -rf include/ src/ ./libyc.a ./rig ./rigc;
}
target "src/rmain.o": "include/", "src/"
{
$ clang -Wall -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE
-D_DARWIN_C_SOURCE -Iinclude/ -g -c -o
src/main.o src/main.c;
}
target "src/rig/main.o": "include/", "src/"
{
$ clang -Wall -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE

1
src/CMakeLists.txt

@ -56,6 +56,7 @@ set("YC_SRC"
"yc.c"
#"stdio.c"
"arith.c"
"main.c"
)
set("YC_EXEC_SRC"

126
src/main.c

@ -0,0 +1,126 @@
/**
* ***** BEGIN LICENSE BLOCK *****
*
* Copyright 2017-2022 Yzena Tech
*
* Licensed under the Yzena Viral User License, Version 0.1 (the "Yzena Viral
* User License" or "YVUL"), the GNU Affero General Public License (the "GNU
* AGPL"), Version 3.0, and the Server Side Public License (the "SSPL"),
* Version 1. You may not use this file except in compliance with all of those
* licenses.
*
* You may obtain a copy of the Yzena Viral User License at
*
* https://yzena.com/yzena-viral-user-license/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Yzena Viral User License is distributed under the
* following disclaimer:
*
* As far as the law allows, this software comes as is, without any
* warranty or condition, and no contributor will be liable to anyone for
* any damages related to this software or this license, under any kind of
* legal claim.
*
* You may obtain a copy of the GNU Affero General Public License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the GNU Affero General Public License is distributed under
* the following disclaimer:
*
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You may obtain a copy of the Server Side Public License at
*
* https://www.mongodb.com/licensing/server-side-public-license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Server Side Public License is distributed under the
* following disclaimer:
*
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Server
* Side Public License for more details.
*
* ****** END LICENSE BLOCK ******
*
* *****************************************************************
*
* ******* BEGIN FILE DESCRIPTION *******
*
* Source file with main(), to be dispatched to the correct program. This is
* separate because all programs need the same setup.
*
* ******** END FILE DESCRIPTION ********
*/
#include <yc/yc.h>
#include "main.h"
#include "rig/rig.h"
static const y_Main mains[] = {
{ .name = y_PATHSTR("rigc"), .func = rigc_main, .need_children = false, .need_timers = false },
{ .name = y_PATHSTR("rig"), .func = rig_main, .need_children = true, .need_timers = true },
};
int
main(int argc, y_pchar* argv[])
{
y_Status s;
y_MainFunc mainfunc = NULL;
bool need_children = false;
bool need_timers = false;
size_t i;
if (y_err(argv == NULL || argv[0] == NULL))
{
// We don't have output at this point; we need to just quit.
exit((int) y_status_exits[y_STATUS_MISSING_CMD_LINE_ARG]);
}
// This is before y_main() because I only want to start the signal/process
// thread if it is needed. This function is also specifically written to be
// safe in this case.
y_pchar* b = y_pbasename(argv[0]);
for (i = 0; i < sizeof(mains) / sizeof(y_Main); ++i)
{
if (!y_pstrcmp(b, mains[i].name))
{
mainfunc = mains[i].func;
need_children = mains[i].need_children;
need_timers = mains[i].need_timers;
break;
}
}
s = y_main(need_children, need_timers);
if (y_err(s != y_STATUS_SUCCESS)) y_errexit(s);
// This is after the call to y_main() in order to have I/O available.
if (y_err(mainfunc == NULL))
{
y_panica("Unrecognized command name");
}
y_StackPool p = y_strucon_stackpool();
y_stackpool_enterScope(p);
s = mainfunc(argc, argv);
#ifdef YC_DEBUG
y_stackpool_exitScope(p);
#endif // YC_DEBUG
// TODO: Make sure every error path prints a message.
y_exit(y_status_exits[s]);
}

115
src/main.h

@ -0,0 +1,115 @@
/**
* ***** BEGIN LICENSE BLOCK *****
*
* Copyright 2017-2022 Yzena Tech
*
* Licensed under the Yzena Viral User License, Version 0.1 (the "Yzena Viral
* User License" or "YVUL"), the GNU Affero General Public License (the "GNU
* AGPL"), Version 3.0, and the Server Side Public License (the "SSPL"),
* Version 1. You may not use this file except in compliance with all of those
* licenses.
*
* You may obtain a copy of the Yzena Viral User License at
*
* https://yzena.com/yzena-viral-user-license/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Yzena Viral User License is distributed under the
* following disclaimer:
*
* As far as the law allows, this software comes as is, without any
* warranty or condition, and no contributor will be liable to anyone for
* any damages related to this software or this license, under any kind of
* legal claim.
*
* You may obtain a copy of the GNU Affero General Public License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the GNU Affero General Public License is distributed under
* the following disclaimer:
*
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You may obtain a copy of the Server Side Public License at
*
* https://www.mongodb.com/licensing/server-side-public-license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Server Side Public License is distributed under the
* following disclaimer:
*
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Server
* Side Public License for more details.
*
* ****** END LICENSE BLOCK ******
*
* *****************************************************************
*
* ******* BEGIN FILE DESCRIPTION *******
*
* Definitions needed for a main file.
*
* ******** END FILE DESCRIPTION ********
*/
#ifndef YC_MAIN_PRIVATE_H
#define YC_MAIN_PRIVATE_H
/* For C++ compatibility */
#ifdef __cplusplus
extern "C" {
#endif
#include <yc/yc.h>
#include "yc.h"
//! @cond INTERNAL
/**
* @file src/main.h
*/
/**
* @defgroup main_internal main_internal
* @brief Internal definitions for the main() function.
* @{
*/
/**
* A struct with information about a program.
*/
typedef struct y_Main
{
/// The name of the program.
const y_pchar* const name;
/// The main() function to call.
y_MainFunc func;
/// Whether the program needs child processes.
bool need_children;
/// Whether the program needs timers.
bool need_timers;
} y_Main;
/**
* @}
*/
//! @endcond INTERNAL
#ifdef __cplusplus
}
#endif
#endif // YC_MAIN_PRIVATE_H

59
src/rig/main.c

@ -54,7 +54,7 @@
*
* ******* BEGIN FILE DESCRIPTION *******
*
* Source file with main() for Rig.
* Source file with main functions for Rig.
*
* ******** END FILE DESCRIPTION ********
*/
@ -154,7 +154,7 @@ rigc_getenv(y_Gaml g)
return s;
}
static y_Status
y_Status
rigc_main(int argc, y_pchar* argv[])
{
y_Status s;
@ -252,7 +252,7 @@ static y_OptLong rig_opts[] = {
{ .longname = NULL, .shortname = 0, y_OPT_NONE },
};
static y_Status
y_Status
rig_main(int argc, y_pchar* argv[])
{
y_Status s;
@ -342,56 +342,3 @@ rig_main(int argc, y_pchar* argv[])
return s;
}
int
main(int argc, y_pchar* argv[])
{
y_Status s;
y_MainFunc mainfunc = NULL;
bool need_children = false;
bool need_timers = false;
if (y_err(argv == NULL || argv[0] == NULL))
{
// We don't have output at this point; we need to just quit.
exit((int) y_status_exits[y_STATUS_MISSING_CMD_LINE_ARG]);
}
// This is before y_main() because I only want to start the signal/process
// thread if it is needed. This function is also specifically written to be
// safe in this case.
y_pchar* b = y_pbasename(argv[0]);
if (!y_pstrcmp(b, y_PATHSTR("rig")))
{
mainfunc = rig_main;
need_children = true;
need_timers = true;
}
else if (!y_pstrcmp(b, y_PATHSTR("rigc")))
{
mainfunc = rigc_main;
}
s = y_main(need_children, need_timers);
if (y_err(s != y_STATUS_SUCCESS)) y_errexit(s);
// This is after the call to y_main() in order to have I/O available.
if (y_err(mainfunc == NULL))
{
y_panica("Unrecognized command name");
}
y_StackPool p = y_strucon_stackpool();
y_stackpool_enterScope(p);
s = mainfunc(argc, argv);
#ifdef YC_DEBUG
y_stackpool_exitScope(p);
#endif // YC_DEBUG
// TODO: Make sure every error path prints a message.
y_exit(y_status_exits[s]);
}

22
src/rig/rig.h

@ -1046,6 +1046,28 @@ extern const size_t rig_envvars_size;
y_Status
rig_fullbuild(rig_TargetIDArray tgts, size_t ncores);
/**
* The @a y_MainFunc for the `rigc` binary.
* @param argc The number of command-line arguments, including the program
* name.
* @param argv The command-line arguments.
* @return An error code, if any.
* @pre @a argv must not be NULL.
*/
y_Status
rigc_main(int argc, y_pchar* argv[]) y_allnonnull;
/**
* The @a y_MainFunc for the `rig` binary.
* @param argc The number of command-line arguments, including the program
* name.
* @param argv The command-line arguments.
* @return An error code, if any.
* @pre @a argv must not be NULL.
*/
y_Status
rig_main(int argc, y_pchar* argv[]) y_allnonnull;
/**
* @}
*/

Loading…
Cancel
Save