Skip to content

Commit bc00434

Browse files
committed
Add argp usage to parse command line arguments
Create new parse_options function to leverage the GNU C library's argp header to parse command line arguments.
1 parent 7cd9e86 commit bc00434

File tree

3 files changed

+166
-73
lines changed

3 files changed

+166
-73
lines changed

src/main.c

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <jansson.h>
1010

1111
#include "common.h"
12+
#include "options.h"
1213
#include "curl.h"
1314
#include "git.h"
1415
#include "github.h"
@@ -21,8 +22,6 @@
2122
#define REMOTE_BUFSIZE 8
2223
#define ASSET_BUFSIZE 8
2324

24-
int parse_options(int argc, char *argv[], int *n_assets);
25-
2625
char opt_draft = 0;
2726
char opt_prerelease = 0;
2827
char *opt_remote;
@@ -34,11 +33,23 @@ const char *base_url = "https://api.github.com";
3433

3534
int main(int argc, char *argv[])
3635
{
36+
struct arguments args = parse_options(argc, argv);
37+
printf("draft: %s\npre: %s\ntok: %s\ngen: %s\nrem: %s\n",
38+
args.draft ? "yes" : "no",
39+
args.prerelease ? "yes" : "no",
40+
args.token,
41+
args.generate_token ? "yes" : "no",
42+
args.remote);
43+
printf("assets:\n");
44+
for (int i = 0; args.assets[i]; i++)
45+
printf("%s\n", args.assets[i]);
46+
return 0;
47+
3748
argv0 = argv[0];
3849
int n_assets;
39-
int result = parse_options(argc, argv, &n_assets);
40-
if (result)
41-
return result;
50+
/* int result = parse_options(argc, argv, &n_assets); */
51+
/* if (result) */
52+
/* return result; */
4253

4354
// initialize git
4455
git_libgit2_init();
@@ -491,71 +502,71 @@ int main(int argc, char *argv[])
491502
}
492503
}
493504

494-
int parse_options(int argc, char *argv[], int *n_assets)
495-
{
496-
*n_assets = 0;
497-
int asset_bufsize = 0;
498-
opt_assets = malloc(asset_bufsize * sizeof(char*));
499-
for (int i = 1; i < argc; i++)
500-
{
501-
if (strcmp(argv[i], "--draft") == 0)
502-
opt_draft = 1;
503-
if (strcmp(argv[i], "--prerelease") == 0)
504-
opt_prerelease = 1;
505-
if (strcmp(argv[i], "--token") == 0)
506-
{
507-
if (argv[i + 1][0] == '-' || !argv[i + 1])
508-
{
509-
fprintf(stderr, ERR "Option %s requires argument\n", argv[i]);
510-
return 1;
511-
}
512-
char *arg_github_token = malloc(strlen(argv[i + 1]) * sizeof(char));
513-
strcpy(arg_github_token, argv[i + 1]);
514-
opt_github_token = arg_github_token;
515-
}
516-
if (strcmp(argv[i], "--generate-token") == 0)
517-
{
518-
puts(github_generate_token());
519-
return 0;
520-
}
521-
if (strcmp(argv[i], "--remote") == 0)
522-
{
523-
if (argv[i + 1][0] == '-' || !argv[i + 1])
524-
{
525-
fprintf(stderr, ERR "Option %s requires argument\n", argv[i]);
526-
return 1;
527-
}
528-
opt_remote = malloc(strlen(argv[i + 1]) * sizeof(char));
529-
strcpy(opt_remote, argv[i + 1]);
530-
}
531-
if (strcmp(argv[i], "--assets") == 0)
532-
{
533-
if (argv[i + 1][0] == '-' || !argv[i + 1])
534-
{
535-
fprintf(stderr, ERR "Option %s requires argument\n", argv[i]);
536-
return 1;
537-
}
538-
539-
i++;
540-
for (i; i < argc && argv[i][0] != '-'; i++)
541-
{
542-
char dup = 0;
543-
for (int j = 0; j < *n_assets; j++)
544-
{
545-
if (strcmp(opt_assets[j], argv[i]) == 0)
546-
dup = 1;
547-
}
548-
if (dup)
549-
continue;
550-
551-
if (*n_assets + 1 > asset_bufsize)
552-
{
553-
asset_bufsize += ASSET_BUFSIZE;
554-
opt_assets = realloc(opt_assets, asset_bufsize * sizeof(char*));
555-
}
556-
opt_assets[(*n_assets)++] = argv[i];
557-
}
558-
}
559-
}
560-
return 0;
561-
}
505+
/* int parse_options(int argc, char *argv[], int *n_assets) */
506+
/* { */
507+
/* *n_assets = 0; */
508+
/* int asset_bufsize = 0; */
509+
/* opt_assets = malloc(asset_bufsize * sizeof(char*)); */
510+
/* for (int i = 1; i < argc; i++) */
511+
/* { */
512+
/* if (strcmp(argv[i], "--draft") == 0) */
513+
/* opt_draft = 1; */
514+
/* if (strcmp(argv[i], "--prerelease") == 0) */
515+
/* opt_prerelease = 1; */
516+
/* if (strcmp(argv[i], "--token") == 0) */
517+
/* { */
518+
/* if (argv[i + 1][0] == '-' || !argv[i + 1]) */
519+
/* { */
520+
/* fprintf(stderr, ERR "Option %s requires argument\n", argv[i]); */
521+
/* return 1; */
522+
/* } */
523+
/* char *arg_github_token = malloc(strlen(argv[i + 1]) * sizeof(char)); */
524+
/* strcpy(arg_github_token, argv[i + 1]); */
525+
/* opt_github_token = arg_github_token; */
526+
/* } */
527+
/* if (strcmp(argv[i], "--generate-token") == 0) */
528+
/* { */
529+
/* puts(github_generate_token()); */
530+
/* return 0; */
531+
/* } */
532+
/* if (strcmp(argv[i], "--remote") == 0) */
533+
/* { */
534+
/* if (argv[i + 1][0] == '-' || !argv[i + 1]) */
535+
/* { */
536+
/* fprintf(stderr, ERR "Option %s requires argument\n", argv[i]); */
537+
/* return 1; */
538+
/* } */
539+
/* opt_remote = malloc(strlen(argv[i + 1]) * sizeof(char)); */
540+
/* strcpy(opt_remote, argv[i + 1]); */
541+
/* } */
542+
/* if (strcmp(argv[i], "--assets") == 0) */
543+
/* { */
544+
/* if (argv[i + 1][0] == '-' || !argv[i + 1]) */
545+
/* { */
546+
/* fprintf(stderr, ERR "Option %s requires argument\n", argv[i]); */
547+
/* return 1; */
548+
/* } */
549+
550+
/* i++; */
551+
/* for (i; i < argc && argv[i][0] != '-'; i++) */
552+
/* { */
553+
/* char dup = 0; */
554+
/* for (int j = 0; j < *n_assets; j++) */
555+
/* { */
556+
/* if (strcmp(opt_assets[j], argv[i]) == 0) */
557+
/* dup = 1; */
558+
/* } */
559+
/* if (dup) */
560+
/* continue; */
561+
562+
/* if (*n_assets + 1 > asset_bufsize) */
563+
/* { */
564+
/* asset_bufsize += ASSET_BUFSIZE; */
565+
/* opt_assets = realloc(opt_assets, asset_bufsize * sizeof(char*)); */
566+
/* } */
567+
/* opt_assets[(*n_assets)++] = argv[i]; */
568+
/* } */
569+
/* } */
570+
/* } */
571+
/* return 0; */
572+
/* } */

src/options.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "options.h"
2+
3+
const char *argp_program_version =
4+
"hubrelease 0.1.0";
5+
const char *argp_program_bug_address =
6+
"https://github.com/MarkusGordathian/hubrelease/issues";
7+
static char doc[] =
8+
"hubrelease -- automate the creation of GitHub releases";
9+
static char args_doc[] = "[ASSET...]";
10+
11+
static struct argp_option options[] = {
12+
{"draft", 'd', 0, 0, "Mark release as draft"},
13+
{"prerelease", 'p', 0, 0, "Mark release as prerelease"},
14+
{"generate-token", 'g', 0, 0, "Generate GitHub authentication token and exit"},
15+
{"token", 't', "TOKEN", 0, "GitHub authentication token"},
16+
{"remote", 'r', "REMOTE", 0, "Specify remote to parse to GitHub URL"},
17+
{ 0 }
18+
};
19+
20+
static error_t parse_opt(int key, char *arg, struct argp_state *state)
21+
{
22+
struct arguments *arguments = state->input;
23+
24+
switch (key)
25+
{
26+
case 'd':
27+
arguments->draft = 1;
28+
break;
29+
case 'p':
30+
arguments->prerelease = 1;
31+
break;
32+
case 'g':
33+
arguments->generate_token = 1;
34+
break;
35+
case 't':
36+
arguments->token = arg;
37+
break;
38+
case 'r':
39+
arguments->remote = arg;
40+
break;
41+
42+
case ARGP_KEY_ARG:
43+
// finished parsing options
44+
// set the assets pointer to the address of the first asset argument
45+
arguments->assets = &state->argv[state->next - 1];
46+
state->next = state->argc;
47+
break;
48+
49+
default:
50+
return ARGP_ERR_UNKNOWN;
51+
}
52+
return 0;
53+
}
54+
55+
static struct argp argp = { options, parse_opt, args_doc, doc };
56+
57+
struct arguments parse_options(int argc, char *argv[])
58+
{
59+
struct arguments arguments;
60+
arguments.draft = 0;
61+
arguments.prerelease = 0;
62+
arguments.generate_token = 0;
63+
arguments.token = NULL;
64+
arguments.remote = NULL;
65+
arguments.assets = NULL;
66+
argp_parse(&argp, argc, argv, 0, 0, &arguments);
67+
return arguments;
68+
}

src/options.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef __RELEASER_OPTIONS_H__
2+
#define __RELEASER_OPTIONS_H__
3+
4+
#include <argp.h>
5+
6+
struct arguments {
7+
int draft, prerelease;
8+
char *token, *remote, **assets;
9+
int generate_token;
10+
};
11+
12+
struct arguments parse_options(int argc, char *argv[]);
13+
14+
#endif

0 commit comments

Comments
 (0)