C LibPCRE TRUE/FALSE issue - c

Got a little problem in a function while iterating between FALSE and TRUE. If I use the function as main function it works (the PCRE pattern matches ok), when I want to call that function from main() then I have a problem and is no match. I think I did some logic error.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcre.h>
typedef enum {FALSE, TRUE} bool;
static const char sub[] =
"12345678901234567890^otherstrings^and^digits12345678901234567890";
bool CheckMyDigit(const char *subject)
{
static const char my_pattern[] = "([0-9]{20})(?=[\\^=])";
const char *errtext = NULL;
int errofs = 0;
pcre* recc = pcre_compile(my_pattern, 0, &errtext, &errofs, NULL);
if (recc != NULL)
{
int ovcc[9];
int rccc = pcre_exec(recc, NULL, subject, sizeof(subject), 0, 0, ovcc, 9);
if (rccc >= 0)
{
const char *spcc = NULL;
pcre_get_substring(subject, ovcc, rccc, 0, &spcc);
printf("%s\n", spcc);
pcre_free_substring(spcc);
return TRUE;
}
else
{
return FALSE;
}
}
pcre_free(recc);
}
int main()
{
if(CheckMyDigit(sub) == TRUE) {
printf("Match!\n");
}
else
{
printf("Error!\n");
}
return 0;
}
Any idea where am I wrong?

Problem is, you are using sizeof instead of string length :
pcre_exec(recc, NULL, subject, sizeof(subject), 0, 0, ovcc, 9
^^^^^^^^^^^^^^^
It should be:
pcre_exec(recc, NULL, subject, strlen(subject), 0, 0, ovcc, 9
It runs in main() function where I think you uses sub array it self and sizeof(sub) gives number of chars + 1, but in function you sizeof(subjest) == sizeof (char*) in your system.

Related

How to get top-level windows and their names using libxcb

I have a Linux desktop with 2 open windows: a terminal and a browser. I'm trying to get the name of those windows with libxcb. Here's my code based on examples I found at https://www.systutorials.com/docs/linux/man/3-xcb_query_tree_reply/
Here's my code:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <xcb/xcb.h>
void get_children(xcb_connection_t* c, xcb_window_t window, xcb_window_t** children, int* count)
{
*count = 0;
*children = NULL;
auto cookie = xcb_query_tree(c, window);
auto reply = xcb_query_tree_reply(c, cookie, NULL);
if (reply)
{
*count = xcb_query_tree_children_length(reply);
*children = xcb_query_tree_children(reply);
free(reply);
}
}
void get_name(xcb_connection_t* c, xcb_window_t window, char** name, int* length)
{
*length = 0;
*name = NULL;
auto cookie = xcb_get_property(c, 0, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 0);
auto reply = xcb_get_property_reply(c, cookie, NULL);
if (reply)
{
*length = xcb_get_property_value_length(reply);
*name = (char*)xcb_get_property_value(reply);
free(reply);
}
}
int main()
{
auto c = xcb_connect(":0.0", NULL);
auto screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
auto rootWindow = screen->root;
int nChildren;
xcb_window_t* children;
get_children(c, screen->root, &children, &nChildren);
for (int i = 0; i < nChildren; i++)
{
auto wid = children[i];
int length;
char* name;
get_name(c, wid, &name, &length);
printf("%u %d\n", wid, length);
}
return 0;
}
This returns 40 windows all with their name's length of 0. For example:
20971989 0
20971802 0
20972112 0
20972308 0
... (truncated for brevity)
I'm trying to get something like the output of wmctrl -l.
What am I doing wrong?
I figured out the problem. I needed to add a length to the xcb_get_property function call. The following code works.
auto cookie = xcb_get_property(c, 0, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000);

how to add if statement while verifying string with Regular Expressions in C

I need to verify a String(string:89dree01) with regular expression ([a-zA-Z0-9]*) using if condition in C like so:
if(string=regex) {}
Could someone help me with this?
Below is the code snippet:
#include <regex.h>
#include <stdio.h>
int main()
{
regex_t * regex = "[a-zA-Z0-9]*";
int value;
value = regcomp(regex,"89dree01", 0);
if (value == 0) {
LOG("RegEx compiled successfully.");
}
else {
LOG("Compilation error.");
}
return 0;
}
You're not using the POSIX regexp library quite correctly.
Here's an example that checks whether arguments given on the command line match that regexp (slightly modified).
#include <regex.h>
#include <stdio.h>
int main(int argc, char **argv) {
regex_t regex;
if (regcomp(&regex, "^[a-zA-Z0-9]+$", REG_NOSUB | REG_EXTENDED)) {
return 1;
}
for (int i = 1; i < argc; i++) {
int status = regexec(&regex, argv[i], 0, NULL, 0);
printf("%s: %s\n", argv[i], status == REG_NOMATCH ? "no match" : "matched");
}
return 0;
}
~/Desktop $ gcc -o s s.c
~/Desktop $ ./s aaa bb0 00a11 ..--
aaa: matched
bb0: matched
00a11: matched
..--: no match
Edit:
Simply (if inefficiently) put, you can wrap this in a function:
int does_regexp_match(const char *string, const char *regexp) {
regex_t r;
if (regcomp(&r, regexp, REG_NOSUB | REG_EXTENDED)) {
return -1;
}
return regexec(&r, string, 0, NULL, 0) == 0 ? 1 : 0;
}
if(does_regexp_match("89dree01", "^[a-zA-Z0-9]+$") == 1) {
// it's a match
}

is it possible to use getopt_long to parse arrays of strings similar to command line arguments in a C program?

I am aware that getopt should be used to parse command line arguments, and not strings.
However, I am confused by the fact that if I pass it an array of strings that "looks like" the argv variable, getopt_long seems to work, but only the first time that I call it. For the second, and all the subsequent times, that I call it it ignores any arguments and returns the default ones.
The reason I am doing this is that I am turning an application that used to take command line arguments in an "interactive" version of it that asks the user for some arguments, then does some actions based on those arguments, then asks for more arguments and so on.
The following code is a minimal example that reproduces the error
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters{
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
int c;
p->d = "default name";
while (1)
{
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "d:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 'd': p->d = optarg;
break;
default:
printf("wrong option specification\n");
exit(-1);
}
}
return 0 ;
}
int main () {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
The output of this code is
I think the data is: first
I think the data is: default name
From the manual page for getopt:
In order to use getopt() to evaluate multiple sets of arguments, or
to evaluate a single set of arguments multiple times, the variable
optreset must be set to 1 before the second and each additional
set of calls to getopt(), and the variable optind must be
reinitialized.
Modifying your code slightly gives you the desired results:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters {
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
p->d = "default name";
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
optreset = 1; /* ADD THIS */
optind = 1; /* ADD THIS */
int c = getopt_long(argc, argv, "d:",
long_options, &option_index);
switch ( c )
{
case -1:
break;
case 'd':
p->d = optarg;
break;
default:
printf("in default case...\n");
printf("wrong option specification\n");
exit(EXIT_FAILURE);
}
return 0;
}
int main(void) {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
with output:
paul#horus:~/src/sandbox$ ./go
I think the data is: first
I think the data is: second
paul#horus:~/src/sandbox$

regular expressions in C match and print

I have lines from file like this:
{123} {12.3.2015 moday} {THIS IS A TEST}
is It possible to get every value between brackets {} and insert into array?
Also I wold like to know if there is some other solution for this problem...
to get like this:
array( 123,
'12.3.2015 moday',
'THIS IS A TEST'
)
My try:
int r;
regex_t reg;
regmatch_t match[2];
char *line = "{123} {12.3.2015 moday} {THIS IS A TEST}";
regcomp(&reg, "[{](.*?)*[}]", REG_ICASE | REG_EXTENDED);
r = regexec(&reg, line, 2, match, 0);
if (r == 0) {
printf("Match!\n");
printf("0: [%.*s]\n", match[0].rm_eo - match[0].rm_so, line + match[0].rm_so);
printf("1: %.*s\n", match[1].rm_eo - match[1].rm_so, line + match[1].rm_so);
} else {
printf("NO match!\n");
}
This will result:
123} {12.3.2015 moday} {THIS IS A TEST
Anyone know how to improve this?
To help you you can use the regex101 website which is really useful.
Then I suggest you to use this regex:
/(?<=\{).*?(?=\})/g
Or any of these ones:
/\{\K.*?(?=\})/g
/\{\K[^\}]+/g
/\{(.*?)\}/g
Also available here for the first one:
https://regex101.com/r/bB6sE8/1
In C you could start with this which is an example for here:
#include <stdio.h>
#include <string.h>
#include <regex.h>
int main ()
{
char * source = "{123} {12.3.2015 moday} {THIS IS A TEST}";
char * regexString = "{([^}]*)}";
size_t maxGroups = 10;
regex_t regexCompiled;
regmatch_t groupArray[10];
unsigned int m;
char * cursor;
if (regcomp(&regexCompiled, regexString, REG_EXTENDED))
{
printf("Could not compile regular expression.\n");
return 1;
};
cursor = source;
while (!regexec(&regexCompiled, cursor, 10, groupArray, 0))
{
unsigned int offset = 0;
if (groupArray[1].rm_so == -1)
break; // No more groups
offset = groupArray[1].rm_eo;
char cursorCopy[strlen(cursor) + 1];
strcpy(cursorCopy, cursor);
cursorCopy[groupArray[1].rm_eo] = 0;
printf("%s\n", cursorCopy + groupArray[1].rm_so);
cursor += offset;
}
regfree(&regexCompiled);
return 0;
}

getopt_long don't return 0 when have flag set in struct option

I met a problem when using getopt_long in C. As is descripted, in the structure as follows:
struct option{
const char *name;
int has_arg;
int *flag;
int val;
};
If flag is set, getopt_long should return 0 and set *flag as val.
But in my code, getopt_long return val and *flag stay unchanged. The code is as follows:
#include<stdio.h>
#include<getopt.h>
int help;
int output;
int verbose;
const char *short_option = "ho:v";
const struct option long_options[] = {
{"help", 0, &help, 'h'},
{"output", 1, &output, 'o'},
{"verbose", 0, &verbose, 'v'},
{NULL, 0, NULL, 0}
};
void print_help()
{
printf("in option help: \n");
}
void print_output(char *content)
{
printf("in option output: argument is %s\n",content);
}
void print_verbose()
{
printf("in option verbose\n");
}
void print_args()
{
printf("help is %d\n",help);
printf("output is %d\n",output);
printf("verbose is %c\n",verbose);
}
int main(int argc, char **argv)
{
int next_option;
while( (next_option = getopt_long(argc, argv, short_option, long_options, NULL )) == 0)
{
printf("next_option is %c\n",next_option);
print_args();
}
return 0;
}
Anyone can help?
If you check the manual page, you will see that:
getopt_long() and getopt_long_only() also return the option character when a short option is recognized. For a long option, they return val if flag is NULL, and 0 otherwise.
So if you use the short option when invoking your program, it will return that option character. For the function to behave as you want, you must use the long argument when invoking your program.

Resources