Skip to content
Snippets Groups Projects
Commit e21c7a11 authored by Anders Lindh Olsson's avatar Anders Lindh Olsson :8ball:
Browse files

Apply pre-commit

parent 6c3e5f49
No related branches found
No related tags found
No related merge requests found
#include "asprintf.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "asprintf.h"
/* some implementations have __va_copy instead of va_copy */
#if !defined(va_copy) && defined (__va_copy)
#if !defined(va_copy) && defined(__va_copy)
#define va_copy __va_copy
#endif
int vasprintf(char** pbuffer, const char* format, va_list ap)
{
int len = -1;
int vasprintf(char **pbuffer, const char *format, va_list ap) {
int len = -1;
#ifdef va_copy
va_list ap2;
va_copy(ap2, ap);
va_list ap2;
va_copy(ap2, ap);
#else
/* if we have no va_copy, we probably don't need one */
#define ap2 ap
/* if we have no va_copy, we probably don't need one */
#define ap2 ap
#endif
#if defined(_WIN32)
len = _vscprintf(format, ap2);
len = _vscprintf(format, ap2);
#else
len = vsnprintf(NULL, 0, format, ap2);
len = vsnprintf(NULL, 0, format, ap2);
#endif
#ifdef va_copy
va_end(ap2);
va_end(ap2);
#endif
if (len <= 0)
{
fprintf(stderr, "vasprintf: error calculating needed size\n");
return -1;
}
*pbuffer = malloc(len+1);
if (*pbuffer == NULL) return -1;
return vsprintf(*pbuffer, format, ap);
if (len <= 0) {
fprintf(stderr, "vasprintf: error calculating needed size\n");
return -1;
}
*pbuffer = malloc(len + 1);
if (*pbuffer == NULL)
return -1;
return vsprintf(*pbuffer, format, ap);
}
int asprintf(char** pbuffer, const char* format, ...)
{
va_list ap;
int len;
int asprintf(char **pbuffer, const char *format, ...) {
va_list ap;
int len;
va_start(ap, format);
len = vasprintf(pbuffer, format, ap);
va_end(ap);
return len;
va_start(ap, format);
len = vasprintf(pbuffer, format, ap);
va_end(ap);
return len;
}
......@@ -8,8 +8,10 @@ extern "C" {
#define __attribute__(arg)
#endif
int asprintf(char** pbuffer, const char* format, ...) __attribute__((__format__(__printf__,2,3)));
int vasprintf(char** pbuffer, const char* format, va_list ap) __attribute__((__format__(__printf__,2,0)));
int asprintf(char **pbuffer, const char *format, ...)
__attribute__((__format__(__printf__, 2, 3)));
int vasprintf(char **pbuffer, const char *format, va_list ap)
__attribute__((__format__(__printf__, 2, 0)));
#ifdef __cplusplus
}
#endif
......
......@@ -12,7 +12,7 @@
#define INCdbLoadTemplateh
#include "shareLib.h"
epicsShareFunc int dbLoadTemplate(
const char *sub_file, const char *cmd_collect, const char *path);
epicsShareFunc int dbLoadTemplate(const char *sub_file, const char *cmd_collect,
const char *path);
#endif /*INCdbLoadTemplateh*/
This diff is collapsed.
......@@ -5,15 +5,16 @@
extern {
#endif
extern int exprDebug;
extern int exprDebug;
size_t replaceExpressions(const char* source, char* buffer, size_t buffersize);
/* Resolve integer expressions that are either free standing
* or in parentheses () embedded in an unquoted word.
* Do not resolve expressions in single or double quoted strings.
* An expression optionally starts with a integer format such as %x.
* It consists of integer numbers, operators and parentheses ().
*/
size_t replaceExpressions(const char *source, char *buffer,
size_t buffersize);
/* Resolve integer expressions that are either free standing
* or in parentheses () embedded in an unquoted word.
* Do not resolve expressions in single or double quoted strings.
* An expression optionally starts with a integer format such as %x.
* It consists of integer numbers, operators and parentheses ().
*/
#ifdef __cplusplus
}
......
This diff is collapsed.
......@@ -9,14 +9,17 @@ extern "C" {
#define __attribute__(dummy)
#endif
int require(const char* libname, const char* version, const char* args);
size_t foreachLoadedLib(size_t (*func)(const char* name, const char* version, const char* path, void* arg), void* arg);
const char* getLibVersion(const char* libname);
const char* getLibLocation(const char* libname);
int libversionShow(const char* outfile);
int runScript(const char* filename, const char* args);
int putenvprintf(const char* format, ...) __attribute__((__format__(__printf__,1,2)));
void pathAdd(const char* varname, const char* dirname);
int require(const char *libname, const char *version, const char *args);
size_t foreachLoadedLib(size_t (*func)(const char *name, const char *version,
const char *path, void *arg),
void *arg);
const char *getLibVersion(const char *libname);
const char *getLibLocation(const char *libname);
int libversionShow(const char *outfile);
int runScript(const char *filename, const char *args);
int putenvprintf(const char *format, ...)
__attribute__((__format__(__printf__, 1, 2)));
void pathAdd(const char *varname, const char *dirname);
#ifdef __cplusplus
}
......
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <macLib.h>
#include <dbAccess.h>
#include <initHooks.h>
#include <epicsVersion.h>
#include <errno.h>
#include <initHooks.h>
#include <macLib.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EPICSVER EPICS_VERSION*10000+EPICS_REVISION*100+EPICS_MODIFICATION
#define EPICSVER \
EPICS_VERSION * 10000 + EPICS_REVISION * 100 + EPICS_MODIFICATION
#if defined (_WIN32)
#if defined(_WIN32)
#include "asprintf.h"
#endif
#include <osiFileName.h>
#include <iocsh.h>
#include <osiFileName.h>
epicsShareFunc int epicsShareAPI iocshCmd(const char *cmd);
#include <epicsExport.h>
#define IS_ABS_PATH(filename) (filename[0] == OSI_PATH_SEPARATOR[0]) /* may be different for other OS ? */
#define IS_ABS_PATH(filename) \
(filename[0] == OSI_PATH_SEPARATOR[0]) /* may be different for other OS ? */
#include "expr.h"
#include "require.h"
#define SAVEENV(var) do { old_##var = getenv(#var); if (old_##var) old_##var=strdup(old_##var); } while(0)
#define RESTOREENV(var) do { if(old_##var) { putenvprintf("%s=%s", #var, old_##var); free(old_##var); }} while(0)
int runScriptDebug=0;
int runScript(const char* filename, const char* args)
{
MAC_HANDLE *mac = NULL;
FILE* file = NULL;
char* line_raw = NULL;
char* line_exp = NULL;
long line_raw_size = 256;
long line_exp_size = line_raw_size;
long len;
char** pairs;
int status = 0;
char* old_MODULE = NULL;
char* old_MODULE_DIR = NULL;
if (!filename)
{
fprintf(stderr, "Usage: runScript filename [macro=value,...]\n");
return -1;
}
if (macCreateHandle(&mac,(const char*[]){ "", "environ", NULL, NULL }) != 0) goto error;
macSuppressWarning(mac, 1);
if ((line_exp = malloc(line_exp_size)) == NULL) goto error;
if ((line_raw = malloc(line_raw_size)) == NULL) goto error;
/* add args to macro definitions */
if (args)
{
if (runScriptDebug)
printf("runScript: macParseDefns \"%s\"\n", args);
macParseDefns(mac, (char*)args, &pairs);
macInstallMacros(mac, pairs);
free(pairs);
#define SAVEENV(var) \
do { \
old_##var = getenv(#var); \
if (old_##var) \
old_##var = strdup(old_##var); \
} while (0)
#define RESTOREENV(var) \
do { \
if (old_##var) { \
putenvprintf("%s=%s", #var, old_##var); \
free(old_##var); \
} \
} while (0)
int runScriptDebug = 0;
int runScript(const char *filename, const char *args) {
MAC_HANDLE *mac = NULL;
FILE *file = NULL;
char *line_raw = NULL;
char *line_exp = NULL;
long line_raw_size = 256;
long line_exp_size = line_raw_size;
long len;
char **pairs;
int status = 0;
char *old_MODULE = NULL;
char *old_MODULE_DIR = NULL;
if (!filename) {
fprintf(stderr, "Usage: runScript filename [macro=value,...]\n");
return -1;
}
if (macCreateHandle(&mac, (const char *[]){"", "environ", NULL, NULL}) != 0)
goto error;
macSuppressWarning(mac, 1);
if ((line_exp = malloc(line_exp_size)) == NULL)
goto error;
if ((line_raw = malloc(line_raw_size)) == NULL)
goto error;
/* add args to macro definitions */
if (args) {
if (runScriptDebug)
printf("runScript: macParseDefns \"%s\"\n", args);
macParseDefns(mac, (char *)args, &pairs);
macInstallMacros(mac, pairs);
free(pairs);
}
if (IS_ABS_PATH(filename)) {
file = fopen(filename, "r");
} else {
const char *dirname;
const char *end;
char *fullname;
const char *path = getenv("SCRIPT_PATH");
int dirlen;
for (dirname = path; dirname != NULL; dirname = end) {
end = strchr(dirname, OSI_PATH_LIST_SEPARATOR[0]);
if (end && end[1] == OSI_PATH_SEPARATOR[0] &&
end[2] == OSI_PATH_SEPARATOR[0]) /* "http://..." and friends */
end = strchr(end + 2, OSI_PATH_LIST_SEPARATOR[0]);
if (end)
dirlen = (int)(end++ - dirname);
else
dirlen = (int)strlen(dirname);
if (dirlen == 0)
continue; /* ignore empty path elements */
if (dirname[dirlen - 1] == OSI_PATH_SEPARATOR[0])
dirlen--;
asprintf(&fullname, "%.*s" OSI_PATH_SEPARATOR "%s", dirlen, dirname,
filename);
if (runScriptDebug)
printf("runScript: trying %s\n", fullname);
file = fopen(fullname, "r");
if (!file && (errno & 0xffff) != ENOENT)
perror(fullname);
free(fullname);
if (file)
break;
}
if (IS_ABS_PATH(filename))
{
file = fopen(filename, "r");
}
if (file == NULL) {
perror(filename);
return errno;
}
/* save some environments variables */
SAVEENV(MODULE);
SAVEENV(MODULE_DIR);
/* execute script line by line after expanding macros with arguments or
* environment */
while (fgets(line_raw, line_raw_size, file)) {
char *p, *x;
/* check if we have a line longer than the buffer size */
while (line_raw[(len = (long)strlen(line_raw)) - 1] != '\n' &&
!feof(file)) {
if (runScriptDebug)
printf("runScript partial line: \"%s\"\n", line_raw);
if ((line_raw = realloc(line_raw, line_raw_size *= 2)) == NULL)
goto error;
if (fgets(line_raw + len, line_raw_size - len, file) == NULL)
break;
}
else
{
const char* dirname;
const char* end;
char* fullname;
const char* path = getenv("SCRIPT_PATH");
int dirlen;
for (dirname = path; dirname != NULL; dirname = end)
{
end = strchr(dirname, OSI_PATH_LIST_SEPARATOR[0]);
if (end && end[1] == OSI_PATH_SEPARATOR[0] && end[2] == OSI_PATH_SEPARATOR[0]) /* "http://..." and friends */
end = strchr(end+2, OSI_PATH_LIST_SEPARATOR[0]);
if (end) dirlen = (int)(end++ - dirname);
else dirlen = (int)strlen(dirname);
if (dirlen == 0) continue; /* ignore empty path elements */
if (dirname[dirlen-1] == OSI_PATH_SEPARATOR[0]) dirlen--;
asprintf(&fullname, "%.*s" OSI_PATH_SEPARATOR "%s",
dirlen, dirname, filename);
if (runScriptDebug)
printf("runScript: trying %s\n", fullname);
file = fopen(fullname, "r");
if (!file && (errno & 0xffff) != ENOENT) perror(fullname);
free(fullname);
if (file) break;
}
while (len > 0 && isspace((unsigned char)line_raw[len - 1]))
line_raw[--len] = 0; /* get rid of '\n' and friends */
if (runScriptDebug)
printf("runScript raw line (%ld chars): '%s'\n", len, line_raw);
/* expand and check the buffer size (different epics versions write
* different may number of bytes)*/
while ((len = labs(
macExpandString(mac, line_raw, line_exp, line_exp_size - 1))) >=
line_exp_size - 2) {
if (runScriptDebug)
printf("runScript: grow expand buffer: len=%ld size=%ld\n", len,
line_exp_size);
free(line_exp);
if ((line_exp = malloc(line_exp_size *= 2)) == NULL)
goto error;
}
if (file == NULL) { perror(filename); return errno; }
/* save some environments variables */
SAVEENV(MODULE);
SAVEENV(MODULE_DIR);
/* execute script line by line after expanding macros with arguments or environment */
while (fgets(line_raw, line_raw_size, file))
{
char* p, *x;
/* check if we have a line longer than the buffer size */
while (line_raw[(len = (long)strlen(line_raw))-1] != '\n' && !feof(file))
{
if (runScriptDebug)
printf("runScript partial line: \"%s\"\n", line_raw);
if ((line_raw = realloc(line_raw, line_raw_size *= 2)) == NULL) goto error;
if (fgets(line_raw + len, line_raw_size - len, file) == NULL) break;
}
while (len > 0 && isspace((unsigned char)line_raw[len-1])) line_raw[--len] = 0; /* get rid of '\n' and friends */
if (runScriptDebug)
printf("runScript raw line (%ld chars): '%s'\n", len, line_raw);
/* expand and check the buffer size (different epics versions write different may number of bytes)*/
while ((len = labs(macExpandString(mac, line_raw, line_exp, line_exp_size-1))) >= line_exp_size-2)
{
if (runScriptDebug)
printf("runScript: grow expand buffer: len=%ld size=%ld\n", len, line_exp_size);
free(line_exp);
if ((line_exp = malloc(line_exp_size *= 2)) == NULL) goto error;
}
if (runScriptDebug)
printf("runScript expanded line (%ld chars): '%s'\n", len, line_exp);
printf("%s\n", line_exp);
p = line_exp;
while (isspace((unsigned char)*p)) p++;
if (*p == 0 || *p == '#') continue;
/* find local variable assignments */
if ((x = strpbrk(p, "=(, \t\n\r")) != NULL && *x=='=')
{
*x++ = 0;
replaceExpressions(x, line_raw, line_raw_size);
if (runScriptDebug)
printf("runScript: assign %s=%s\n", p, line_raw);
macPutValue(mac, p, line_raw);
continue;
}
if (runScriptDebug)
printf("runScript: iocshCmd: '%s'\n", line_exp);
status = iocshCmd(line_exp);
if (status != 0) break;
if (runScriptDebug)
printf("runScript expanded line (%ld chars): '%s'\n", len, line_exp);
printf("%s\n", line_exp);
p = line_exp;
while (isspace((unsigned char)*p))
p++;
if (*p == 0 || *p == '#')
continue;
/* find local variable assignments */
if ((x = strpbrk(p, "=(, \t\n\r")) != NULL && *x == '=') {
*x++ = 0;
replaceExpressions(x, line_raw, line_raw_size);
if (runScriptDebug)
printf("runScript: assign %s=%s\n", p, line_raw);
macPutValue(mac, p, line_raw);
continue;
}
goto end;
if (runScriptDebug)
printf("runScript: iocshCmd: '%s'\n", line_exp);
status = iocshCmd(line_exp);
if (status != 0)
break;
}
goto end;
error:
if (errno)
{
status = errno;
perror("runScript");
}
if (errno) {
status = errno;
perror("runScript");
}
end:
free(line_raw);
free(line_exp);
if (mac) macDeleteHandle(mac);
if (file) fclose(file);
free(line_raw);
free(line_exp);
if (mac)
macDeleteHandle(mac);
if (file)
fclose(file);
/* restore environment */
RESTOREENV(MODULE);
RESTOREENV(MODULE_DIR);
return status;
}
/* restore environment */
RESTOREENV(MODULE);
RESTOREENV(MODULE_DIR);
struct cmditem {
struct cmditem *next;
int type;
union {
char *a[12];
char cmd[256];
} x;
} * cmdlist, **cmdlast = &cmdlist;
return status;
}
void afterInitHook(initHookState state) {
struct cmditem *item;
struct cmditem
{
struct cmditem* next;
int type;
union {
char* a[12];
char cmd[256];
} x;
} *cmdlist, **cmdlast=&cmdlist;
void afterInitHook(initHookState state)
{
struct cmditem *item;
if (state !=
if (state !=
#ifdef INCinitHooksh
/* old: without iocPause etc */
initHookAfterInterruptAccept
/* old: without iocPause etc */
initHookAfterInterruptAccept
#else
/* new: with iocPause etc */
initHookAfterIocRunning
/* new: with iocPause etc */
initHookAfterIocRunning
#endif
) return;
for (item = cmdlist; item != NULL; item = item->next)
{
if (item->type == 1)
{
printf("%s\n", item->x.cmd);
iocshCmd(item->x.cmd);
}
else
((void (*)())item->x.a[0])(item->x.a[1], item->x.a[2], item->x.a[3], item->x.a[4], item->x.a[5],
item->x.a[6], item->x.a[7], item->x.a[8], item->x.a[9], item->x.a[10], item->x.a[11]);
}
)
return;
for (item = cmdlist; item != NULL; item = item->next) {
if (item->type == 1) {
printf("%s\n", item->x.cmd);
iocshCmd(item->x.cmd);
} else
((void (*)())item->x.a[0])(item->x.a[1], item->x.a[2], item->x.a[3],
item->x.a[4], item->x.a[5], item->x.a[6],
item->x.a[7], item->x.a[8], item->x.a[9],
item->x.a[10], item->x.a[11]);
}
}
static int first_time = 1;
static struct cmditem *newItem(char* cmd, int type)
{
struct cmditem *item;
if (!cmd)
{
fprintf(stderr, "usage: afterInit command, args...\n");
return NULL;
}
if (interruptAccept)
{
fprintf(stderr, "afterInit can only be used before iocInit\n");
return NULL;
}
if (first_time)
{
first_time = 0;
initHookRegister(afterInitHook);
}
item = malloc(sizeof(struct cmditem));
if (item == NULL)
{
perror("afterInit");
return NULL;
}
item->type = type;
item->next = NULL;
*cmdlast = item;
cmdlast = &item->next;
return item;
static struct cmditem *newItem(char *cmd, int type) {
struct cmditem *item;
if (!cmd) {
fprintf(stderr, "usage: afterInit command, args...\n");
return NULL;
}
if (interruptAccept) {
fprintf(stderr, "afterInit can only be used before iocInit\n");
return NULL;
}
if (first_time) {
first_time = 0;
initHookRegister(afterInitHook);
}
item = malloc(sizeof(struct cmditem));
if (item == NULL) {
perror("afterInit");
return NULL;
}
item->type = type;
item->next = NULL;
*cmdlast = item;
cmdlast = &item->next;
return item;
}
int afterInit(char* cmd, char* a1, char* a2, char* a3, char* a4, char* a5, char* a6, char* a7, char* a8, char* a9, char* a10, char* a11)
{
struct cmditem *item = newItem(cmd, 0);
if (!item) return -1;
item->x.a[0] = cmd;
item->x.a[1] = a1;
item->x.a[2] = a2;
item->x.a[3] = a3;
item->x.a[4] = a4;
item->x.a[5] = a5;
item->x.a[6] = a6;
item->x.a[7] = a7;
item->x.a[8] = a8;
item->x.a[9] = a9;
item->x.a[10] = a10;
item->x.a[11] = a11;
return 0;
int afterInit(char *cmd, char *a1, char *a2, char *a3, char *a4, char *a5,
char *a6, char *a7, char *a8, char *a9, char *a10, char *a11) {
struct cmditem *item = newItem(cmd, 0);
if (!item)
return -1;
item->x.a[0] = cmd;
item->x.a[1] = a1;
item->x.a[2] = a2;
item->x.a[3] = a3;
item->x.a[4] = a4;
item->x.a[5] = a5;
item->x.a[6] = a6;
item->x.a[7] = a7;
item->x.a[8] = a8;
item->x.a[9] = a9;
item->x.a[10] = a10;
item->x.a[11] = a11;
return 0;
}
epicsExportAddress(int, runScriptDebug);
epicsExportAddress(int, exprDebug);
static const iocshFuncDef runScriptDef = {
"runScript", 2, (const iocshArg *[]) {
&(iocshArg) { "filename", iocshArgString },
&(iocshArg) { "substitutions", iocshArgString },
}};
static void runScriptFunc(const iocshArgBuf *args)
{
runScript(args[0].sval, args[1].sval);
"runScript", 2,
(const iocshArg *[]){
&(iocshArg){"filename", iocshArgString},
&(iocshArg){"substitutions", iocshArgString},
}};
static void runScriptFunc(const iocshArgBuf *args) {
runScript(args[0].sval, args[1].sval);
}
static const iocshFuncDef afterInitDef = {
"afterInit", 1, (const iocshArg *[]) {
&(iocshArg) { "commandline", iocshArgArgv },
}};
static void afterInitFunc(const iocshArgBuf *args)
{
int i, n;
struct cmditem *item = newItem(args[0].aval.av[1], 1);
if (!item) return;
n = sprintf(item->x.cmd, "%.255s", args[0].aval.av[1]);
for (i = 2; i < args[0].aval.ac; i++)
{
if (strpbrk(args[0].aval.av[i], " ,\"\\"))
n += sprintf(item->x.cmd+n, " '%.*s'", 255-3-n, args[0].aval.av[i]);
else
n += sprintf(item->x.cmd+n, " %.*s", 255-1-n, args[0].aval.av[i]);
}
"afterInit", 1,
(const iocshArg *[]){
&(iocshArg){"commandline", iocshArgArgv},
}};
static void afterInitFunc(const iocshArgBuf *args) {
int i, n;
struct cmditem *item = newItem(args[0].aval.av[1], 1);
if (!item)
return;
n = sprintf(item->x.cmd, "%.255s", args[0].aval.av[1]);
for (i = 2; i < args[0].aval.ac; i++) {
if (strpbrk(args[0].aval.av[i], " ,\"\\"))
n += sprintf(item->x.cmd + n, " '%.*s'", 255 - 3 - n, args[0].aval.av[i]);
else
n += sprintf(item->x.cmd + n, " %.*s", 255 - 1 - n, args[0].aval.av[i]);
}
}
static void runScriptRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister (&runScriptDef, runScriptFunc);
iocshRegister (&afterInitDef, afterInitFunc);
}
static void runScriptRegister(void) {
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&runScriptDef, runScriptFunc);
iocshRegister(&afterInitDef, afterInitFunc);
}
}
epicsExportRegistrar(runScriptRegister);
#include <string.h>
#include <stdlib.h>
#include <string.h>
char *strdup(const char *s)
{
char *d = malloc(strlen(s)+1);
if (d) strcpy(d,s);
return d;
char *strdup(const char *s) {
char *d = malloc(strlen(s) + 1);
if (d)
strcpy(d, s);
return d;
}
char *strndup(const char *s, size_t n)
{
size_t l;
char *d;
char *strndup(const char *s, size_t n) {
size_t l;
char *d;
l = strlen(s);
if (n > l) n = l;
d = malloc(n+1);
strncpy(d,s,l);
d[n] = 0;
return d;
l = strlen(s);
if (n > l)
n = l;
d = malloc(n + 1);
strncpy(d, s, l);
d[n] = 0;
return d;
}
#include "version.h"
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "version.h"
void cleanup_semver(semver_t *s)
{
free(s->version_str);
free(s);
void cleanup_semver(semver_t *s) {
free(s->version_str);
free(s);
}
static void init_semver(const char *version, semver_t *s)
{
s->version_str = calloc(strlen(version) + 1, sizeof(char));
strcpy(s->version_str, version);
s->test_str = "";
static void init_semver(const char *version, semver_t *s) {
s->version_str = calloc(strlen(version) + 1, sizeof(char));
strcpy(s->version_str, version);
s->test_str = "";
s->major = 0;
s->minor = 0;
s->patch = 0;
s->build = -1;
s->major = 0;
s->minor = 0;
s->patch = 0;
s->build = -1;
}
static void fetch_part(char *version_str, const regmatch_t *groups, unsigned int ix, int *part)
{
char tmp;
static void fetch_part(char *version_str, const regmatch_t *groups,
unsigned int ix, int *part) {
char tmp;
tmp = version_str[groups[ix].rm_eo];
version_str[groups[ix].rm_eo] = 0;
*part = atoi(version_str + groups[ix].rm_so);
version_str[groups[ix].rm_eo] = tmp;
tmp = version_str[groups[ix].rm_eo];
version_str[groups[ix].rm_eo] = 0;
*part = atoi(version_str + groups[ix].rm_so);
version_str[groups[ix].rm_eo] = tmp;
}
int parse_semver(const char *version, semver_t *s)
{
static const char* version_regex = "^(([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\+([0-9]+))?)?(.*)$";
static const unsigned int max_regex_groups = 7 + 1;
static const unsigned int major_ix = 2;
static const unsigned int minor_ix = 3;
static const unsigned int patch_ix = 4;
static const unsigned int build_ix = 6;
static const unsigned int test_ix = 7;
int parse_semver(const char *version, semver_t *s) {
static const char *version_regex =
"^(([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\+([0-9]+))?)?(.*)$";
static const unsigned int max_regex_groups = 7 + 1;
static const unsigned int major_ix = 2;
static const unsigned int minor_ix = 3;
static const unsigned int patch_ix = 4;
static const unsigned int build_ix = 6;
static const unsigned int test_ix = 7;
regex_t compiled;
regmatch_t groups[max_regex_groups];
regex_t compiled;
regmatch_t groups[max_regex_groups];
init_semver(version, s);
init_semver(version, s);
if (s->version_str == NULL || s->version_str[0] == 0)
{
return 1;
}
if (s->version_str == NULL || s->version_str[0] == 0) {
return 1;
}
if (regcomp(&compiled, version_regex, REG_EXTENDED))
{
return 1;
}
if (regcomp(&compiled, version_regex, REG_EXTENDED)) {
return 1;
}
if (regexec(&compiled, s->version_str, max_regex_groups, groups, 0) == 0)
{
fetch_part(s->version_str, groups, major_ix, &s->major);
fetch_part(s->version_str, groups, minor_ix, &s->minor);
fetch_part(s->version_str, groups, patch_ix, &s->patch);
if (groups[build_ix].rm_so != (regoff_t)-1)
{
fetch_part(s->version_str, groups, build_ix, &s->build);
}
s->test_str = s->version_str + groups[test_ix].rm_so;
if (regexec(&compiled, s->version_str, max_regex_groups, groups, 0) == 0) {
fetch_part(s->version_str, groups, major_ix, &s->major);
fetch_part(s->version_str, groups, minor_ix, &s->minor);
fetch_part(s->version_str, groups, patch_ix, &s->patch);
if (groups[build_ix].rm_so != (regoff_t)-1) {
fetch_part(s->version_str, groups, build_ix, &s->build);
}
return 0;
s->test_str = s->version_str + groups[test_ix].rm_so;
}
return 0;
}
typedef struct semver_t {
char *version_str;
int major;
int minor;
int patch;
int build; // can be negative; implies that build has not been specified
char *test_str;
char *version_str;
int major;
int minor;
int patch;
int build; // can be negative; implies that build has not been specified
char *test_str;
} semver_t;
void cleanup_semver(semver_t *s);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment