{"id":18543918,"url":"https://github.com/itotaljustice/args","last_synced_at":"2025-05-15T05:30:47.790Z","repository":{"id":111601682,"uuid":"366086321","full_name":"ITotalJustice/args","owner":"ITotalJustice","description":"Simple c99 argv parser with zero memory allocation","archived":false,"fork":false,"pushed_at":"2021-05-19T09:10:25.000Z","size":18,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-09T00:15:27.963Z","etag":null,"topics":["argv","argv-parser","c99"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ITotalJustice.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-10T15:15:55.000Z","updated_at":"2022-03-14T10:51:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"2e94224f-5343-4f6a-9584-fe8cd71e3b57","html_url":"https://github.com/ITotalJustice/args","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ITotalJustice%2Fargs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ITotalJustice%2Fargs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ITotalJustice%2Fargs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ITotalJustice%2Fargs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ITotalJustice","download_url":"https://codeload.github.com/ITotalJustice/args/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254281558,"owners_count":22044964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argv","argv-parser","c99"],"created_at":"2024-11-06T20:14:52.812Z","updated_at":"2025-05-15T05:30:47.764Z","avatar_url":"https://github.com/ITotalJustice.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# args\n\nSimple c99 argv parser with zero memory allocation\n\n## How to use\n\nargs is very simple, it allocates no memory and is only a single function call!\n\nFirst, create the meta info for the args you want.\n\n```c\nenum ArgID {\n  ArgID_HELP,\n  ArgID_VERSION,\n  ArgID_FILE,\n};\n\nconst struct ArgsMeta metas[] = {\n  {\n    .key = \"help\",\n    .id = ArgID_HELP,\n    .type = ArgsValueType_NONE,\n    .single = 'h'\n  },\n  {\n    .key = \"version\",\n    .id = ArgID_VERSION,\n    .type = ArgsValueType_NONE,\n    .single = 'v'\n  },\n  {\n    .key = \"file\",\n    .id = ArgID_FILE,\n    .type = ArgsValueType_STR,\n    .single = 'f'\n  },\n};\n```\n\nNext, we need to setup our output data.\n\nNOTE: The number of entries in this array MUST be the same size as the `ArgsMeta` array we created above!\n\n```c\n#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))\n\nstruct Argsdata data[ARRAY_SIZE(metas)] = {0};\n// this is how many entires are filled by the parser!\nunsigned data_count = {0};\n```\n\nFinally, we can call the parse function!\n\n```c\nconst enum ArgsResult result = args_parse(\n  1, argc, argv,\n  metas, ARRAY_SIZE(metas),\n  data, \u0026data_count\n);\n```\n\nNOTE: You might notice that we pass a `1` as the first param. That's just the index that we want to start from.\n\nUsually, `argv[0]` is the path of the program, so we can skip then, hence passing `1`, so we start from `argv[1]`\n\nThe return value of the parser is an enum. in general, `0 == OK`, any negative number is an error, any positive number is `OK` but with with a warning.\n\n```c\nswitch (result) {\n  case ArgsResult_UNWANTED_VALUE:\n  case ArgsResult_BAD_VALUE:\n  case ArgsResult_MISSING_VALUE:\n  case ArgsResult_ERROR:\n    printf(\"Args Error: %d\\n\", result);\n    return -1;\n\n  case ArgsResult_OK:\n  case ArgsResult_EXTRA_ARGS:\n    break;\n}\n```\n\nThe filled out data struct looks like this:\n\n```c\nstruct Argsdata {\n  const char* key; // key, not always NULL terminated\n  unsigned key_len; // actual length of the key\n  union ArgsValue value; // union of value types\n  int id; // your ID that you set for the key\n};\n```\n\nwhere `value` is a union of types:\n\n```c\nunion ArgsValue {\n  const char* s;\n  long long i;\n  double d;\n  bool b;\n};\n```\n\nYou can loop now through the `struct Argsdata` array we created earlier, here's an example\n\n```c\nfor (unsigned i = 0; i \u003c data_count; ++i) {\n  switch (data[i].id) {\n    case ArgID_HELP:\n      printf(\"key: %.*s\\n\", data[i].key_len, data[i].key);\n      break;\n\n    case ArgID_VERSION:\n      printf(\"key: %.*s\\n\", data[i].key_len, data[i].key);\n      break;\n\n    case ArgID_FILE:\n      printf(\"key: %.*s value: %s\\n\", data[i].key_len, data[i].key, data[i].value.s);\n      break;\n  }\n}\n```\n\nThe full example can be seen [here](https://github.com/ITotalJustice/args/blob/master/examples/basic.c)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitotaljustice%2Fargs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitotaljustice%2Fargs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitotaljustice%2Fargs/lists"}