Skip to content
This repository was archived by the owner on Feb 12, 2025. It is now read-only.

Commit 0ca90b6

Browse files
authored
Merge pull request #7 from tsoding/0.0.1
[0.0.1] First official release
2 parents 4a86450 + 391d1ab commit 0ca90b6

File tree

5 files changed

+203
-87
lines changed

5 files changed

+203
-87
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ Explore [nobuild.c](./nobuild.c) file and the [examples](./examples) folder to l
1717

1818
## How to use the library in your own project
1919

20+
Keep in mind that [nobuild.h](./nobuild.h) is an [stb-style](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) header-only library. That means that just including it does not include the implementations of the functions. You have to define `NOBUILD_IMPLEMENTATION` macro before the include. See our [nobuild.c](./nobuild.c) for an example.
21+
2022
1. Copy [nobuild.h](./nobuild.h) to your project
21-
2. Create `nobuild.c` in your project with the build recipe. See our own [nobuild.c](./nobuild.c) for an example.
23+
2. Create `nobuild.c` in your project with the build recipe. See our [nobuild.c](./nobuild.c) for an example.
2224
3. Bootstrap the `nobuild` executable:
2325
- `$ cc nobuild.c -o nobuild` on POSIX systems
2426
- `$ cl.exe nobuild.c` on Windows with MSVC

examples/foreach.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#define NOBUILD_IMPLEMENTATION
12
#include "../nobuild.h"
23

34
void foreach_vargs(int ignore, ...)

examples/string.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#define NOBUILD_IMPLEMENTATION
12
#include "../nobuild.h"
23

34
#define DEMO(expr) \

nobuild.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#define NOBUILD_IMPLEMENTATION
12
#include "./nobuild.h"
23

34
void check_example(const char *example)

nobuild.h

Lines changed: 197 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
// Copyright 2021 Alexey Kutepov <reximkut@gmail.com>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining
4+
// a copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to
8+
// permit persons to whom the Software is furnished to do so, subject to
9+
// the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be
12+
// included in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
//
22+
// ============================================================
23+
//
24+
// nobuild — 0.0.1 — Header only library for writing build recipes in C.
25+
//
26+
// https://github.com/tsoding/nobuild
27+
//
28+
// ============================================================
29+
//
30+
// ChangeLog (https://semver.org/ is implied)
31+
//
32+
// 0.0.1 First Official Release
33+
34+
#ifndef NOBUILD_H_
35+
#define NOBUILD_H_
36+
137
#include <assert.h>
238
#include <stdio.h>
339
#include <stdlib.h>
@@ -9,88 +45,70 @@
945
# define WIN32_LEAN_AND_MEAN
1046
# include "windows.h"
1147
# include <process.h>
48+
// minirent.h HEADER BEGIN ////////////////////////////////////////
49+
// Copyright 2021 Alexey Kutepov <reximkut@gmail.com>
50+
//
51+
// Permission is hereby granted, free of charge, to any person obtaining
52+
// a copy of this software and associated documentation files (the
53+
// "Software"), to deal in the Software without restriction, including
54+
// without limitation the rights to use, copy, modify, merge, publish,
55+
// distribute, sublicense, and/or sell copies of the Software, and to
56+
// permit persons to whom the Software is furnished to do so, subject to
57+
// the following conditions:
58+
//
59+
// The above copyright notice and this permission notice shall be
60+
// included in all copies or substantial portions of the Software.
61+
//
62+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
63+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
65+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
66+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
67+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
68+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69+
//
70+
// ============================================================
71+
//
72+
// minirent — 0.0.1 — A subset of dirent interface for Windows.
73+
//
74+
// https://github.com/tsoding/minirent
75+
//
76+
// ============================================================
77+
//
78+
// ChangeLog (https://semver.org/ is implied)
79+
//
80+
// 0.0.1 First Official Release
81+
82+
#ifndef MINIRENT_H_
83+
#define MINIRENT_H_
84+
85+
#define WIN32_LEAN_AND_MEAN
86+
#include "windows.h"
87+
88+
struct dirent
89+
{
90+
char d_name[MAX_PATH+1];
91+
};
92+
93+
typedef struct DIR DIR;
94+
95+
DIR *opendir(const char *dirpath);
96+
struct dirent *readdir(DIR *dirp);
97+
int closedir(DIR *dirp);
98+
99+
#endif // MINIRENT_H_
100+
// minirent.h HEADER END ////////////////////////////////////////
12101
#else
13102
# include <sys/stat.h>
14103
# include <sys/types.h>
15104
# include <sys/wait.h>
16105
# include <unistd.h>
106+
# include <dirent.h>
17107
#endif // _WIN32
18108

19109
// TODO(#1): no way to disable echo in nobuild scripts
20110
// TODO(#2): no way to ignore fails
21111

22-
#ifdef _WIN32
23-
struct dirent
24-
{
25-
char d_name[MAX_PATH+1];
26-
};
27-
28-
typedef struct {
29-
HANDLE hFind;
30-
WIN32_FIND_DATA data;
31-
struct dirent *dirent;
32-
} DIR;
33-
34-
DIR *opendir(const char *dirpath)
35-
{
36-
assert(dirpath);
37-
38-
char buffer[MAX_PATH];
39-
snprintf(buffer, MAX_PATH, "%s\\*", dirpath);
40-
41-
DIR *dir = (DIR*)calloc(1, sizeof(DIR));
42-
43-
dir->hFind = FindFirstFile(buffer, &dir->data);
44-
if (dir->hFind == INVALID_HANDLE_VALUE) {
45-
goto fail;
46-
}
47-
48-
return dir;
49-
50-
fail:
51-
if (dir) {
52-
free(dir);
53-
}
54-
55-
return NULL;
56-
}
57-
58-
struct dirent *readdir(DIR *dirp)
59-
{
60-
assert(dirp);
61-
62-
if (dirp->dirent == NULL) {
63-
dirp->dirent = (struct dirent*)calloc(1, sizeof(struct dirent));
64-
} else {
65-
if(!FindNextFile(dirp->hFind, &dirp->data)) {
66-
return NULL;
67-
}
68-
}
69-
70-
memset(dirp->dirent->d_name, 0, sizeof(dirp->dirent->d_name));
71-
72-
strncpy(
73-
dirp->dirent->d_name,
74-
dirp->data.cFileName,
75-
sizeof(dirp->dirent->d_name) - 1);
76-
77-
return dirp->dirent;
78-
}
79-
80-
void closedir(DIR *dirp)
81-
{
82-
assert(dirp);
83-
84-
FindClose(dirp->hFind);
85-
if (dirp->dirent) {
86-
free(dirp->dirent);
87-
}
88-
free(dirp);
89-
}
90-
#else
91-
# include <dirent.h>
92-
#endif // _WIN32
93-
94112
#ifdef _WIN32
95113
# define PATH_SEP "\\"
96114
#else
@@ -133,6 +151,109 @@ void closedir(DIR *dirp)
133151
closedir(dir); \
134152
} while(0)
135153

154+
// TODO(#5): there is no way to redirect the output of CMD to a file
155+
#define CMD(...) \
156+
do { \
157+
printf("[INFO] %s\n", CONCAT_SEP(" ", __VA_ARGS__)); \
158+
cmd_impl(69, __VA_ARGS__, NULL); \
159+
} while(0)
160+
161+
const char *concat_impl(int ignore, ...);
162+
const char *concat_sep_impl(const char *sep, ...);
163+
void mkdirs_impl(int ignore, ...);
164+
void cmd_impl(int ignore, ...);
165+
void nobuild_exec(const char **argv);
166+
const char *remove_ext(const char *path);
167+
char *shift(int *argc, char ***argv);
168+
169+
#define CONCAT(...) concat_impl(69, __VA_ARGS__, NULL)
170+
#define CONCAT_SEP(sep, ...) concat_sep_impl(sep, __VA_ARGS__, NULL)
171+
#define PATH(...) CONCAT_SEP(PATH_SEP, __VA_ARGS__)
172+
#define MKDIRS(...) mkdirs_impl(69, __VA_ARGS__, NULL)
173+
174+
#endif // NOBUILD_H_
175+
176+
#ifdef NOBUILD_IMPLEMENTATION
177+
178+
#ifdef _WIN32
179+
// minirent.h IMPLEMENTATION BEGIN ////////////////////////////////////////
180+
struct DIR
181+
{
182+
HANDLE hFind;
183+
WIN32_FIND_DATA data;
184+
struct dirent *dirent;
185+
};
186+
187+
DIR *opendir(const char *dirpath)
188+
{
189+
assert(dirpath);
190+
191+
char buffer[MAX_PATH];
192+
snprintf(buffer, MAX_PATH, "%s\\*", dirpath);
193+
194+
DIR *dir = (DIR*)calloc(1, sizeof(DIR));
195+
196+
dir->hFind = FindFirstFile(buffer, &dir->data);
197+
if (dir->hFind == INVALID_HANDLE_VALUE) {
198+
errno = ENOSYS;
199+
goto fail;
200+
}
201+
202+
return dir;
203+
204+
fail:
205+
if (dir) {
206+
free(dir);
207+
}
208+
209+
return NULL;
210+
}
211+
212+
struct dirent *readdir(DIR *dirp)
213+
{
214+
assert(dirp);
215+
216+
if (dirp->dirent == NULL) {
217+
dirp->dirent = (struct dirent*)calloc(1, sizeof(struct dirent));
218+
} else {
219+
if(!FindNextFile(dirp->hFind, &dirp->data)) {
220+
if (GetLastError() != ERROR_NO_MORE_FILES) {
221+
errno = ENOSYS;
222+
}
223+
224+
return NULL;
225+
}
226+
}
227+
228+
memset(dirp->dirent->d_name, 0, sizeof(dirp->dirent->d_name));
229+
230+
strncpy(
231+
dirp->dirent->d_name,
232+
dirp->data.cFileName,
233+
sizeof(dirp->dirent->d_name) - 1);
234+
235+
return dirp->dirent;
236+
}
237+
238+
int closedir(DIR *dirp)
239+
{
240+
assert(dirp);
241+
242+
if(!FindClose(dirp->hFind)) {
243+
errno = ENOSYS;
244+
return -1;
245+
}
246+
247+
if (dirp->dirent) {
248+
free(dirp->dirent);
249+
}
250+
free(dirp);
251+
252+
return 0;
253+
}
254+
// minirent.h IMPLEMENTATION END ////////////////////////////////////////
255+
#endif // _WIN32
256+
136257
const char *concat_sep_impl(const char *sep, ...)
137258
{
138259
const size_t sep_len = strlen(sep);
@@ -169,10 +290,6 @@ const char *concat_sep_impl(const char *sep, ...)
169290
return result;
170291
}
171292

172-
#define CONCAT_SEP(sep, ...) concat_sep_impl(sep, __VA_ARGS__, NULL)
173-
174-
#define PATH(...) CONCAT_SEP(PATH_SEP, __VA_ARGS__)
175-
176293
void mkdirs_impl(int ignore, ...)
177294
{
178295
size_t length = 0;
@@ -218,8 +335,6 @@ void mkdirs_impl(int ignore, ...)
218335
});
219336
}
220337

221-
#define MKDIRS(...) mkdirs_impl(69, __VA_ARGS__, NULL)
222-
223338
// TODO(#3): there is no way to remove a folder
224339
// TODO(#4): there is no way to remove a file
225340

@@ -244,7 +359,8 @@ const char *concat_impl(int ignore, ...)
244359
return result;
245360
}
246361

247-
#define CONCAT(...) concat_impl(69, __VA_ARGS__, NULL)
362+
363+
248364

249365
void nobuild_exec(const char **argv)
250366
{
@@ -322,13 +438,6 @@ void cmd_impl(int ignore, ...)
322438
nobuild_exec(argv);
323439
}
324440

325-
// TODO(#5): there is no way to redirect the output of CMD to a file
326-
#define CMD(...) \
327-
do { \
328-
printf("[INFO] %s\n", CONCAT_SEP(" ", __VA_ARGS__)); \
329-
cmd_impl(69, __VA_ARGS__, NULL); \
330-
} while(0)
331-
332441
const char *remove_ext(const char *path)
333442
{
334443
size_t n = strlen(path);
@@ -355,3 +464,5 @@ char *shift(int *argc, char ***argv)
355464
*argc -= 1;
356465
return result;
357466
}
467+
468+
#endif // NOBUILD_IMPLEMENTATION

0 commit comments

Comments
 (0)