Undefined reference while using gcc - c

Trying to compile this code and keep getting "undefined reference to..." compiler errors. I'm not sure what's going on. I was told you don't need to include a reference to a ".c" file as long as you reference its ".h" file.
My terminal command: gcc Main.c semaphore.o -L. -lst -o test
/tmp/ccGSIjXz.o: In function `main':
HW3.c:(.text+0x15): undefined reference to `init_buffer'
HW3.c:(.text+0x26): undefined reference to `init_buffer'
HW3.c:(.text+0x37): undefined reference to `init_buffer'
/tmp/ccGSIjXz.o: In function `Thread1':
HW3.c:(.text+0x159): undefined reference to `c_deposit'
/tmp/ccGSIjXz.o: In function `Thread2':
HW3.c:(.text+0x18c): undefined reference to `c_remove'
HW3.c:(.text+0x1b9): undefined reference to `c_deposit'
/tmp/ccGSIjXz.o: In function `Thread3':
HW3.c:(.text+0x1e8): undefined reference to `c_remove'
HW3.c:(.text+0x206): undefined reference to `c_remove'
HW3.c:(.text+0x21a): undefined reference to `c_remove'
HW3.c:(.text+0x238): undefined reference to `c_deposit'
HW3.c:(.text+0x252): undefined reference to `c_deposit'
/tmp/ccGSIjXz.o: In function `Thread4':
HW3.c:(.text+0x28c): undefined reference to `c_remove'
collect2: ld returned 1 exit status
Here's the code:
Main.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "st.h"
#include "buffer.h"
#define MAX_CHARS 81
#define BUFF_SIZE 12
#define NULL_CHAR
typedef struct {
}ThreadInit;
static buffer *buffer1;
static buffer *buffer2;
static buffer *buffer3;
void *Thread1();
void *Thread2();
void *Thread3();
void *Thread4();
int main(int argc, char const *argv[])
{
buffer1=init_buffer(BUFF_SIZE);
buffer2=init_buffer(BUFF_SIZE);
buffer3=init_buffer(BUFF_SIZE);
ThreadInit thread1={};
ThreadInit thread2={};
ThreadInit thread3={};
ThreadInit thread4={};
if (st_thread_create(Thread1(), &thread1, 0, 0) == NULL) {
perror("st_thread_create failed for thread 1");
exit(EXIT_FAILURE);
}
if (st_thread_create(Thread2(), &thread2, 0, 0) == NULL) {
perror("st_thread_create failed for thread 2");
exit(EXIT_FAILURE);
}
if (st_thread_create(Thread3(), &thread3, 0, 0) == NULL) {
perror("st_thread_create failed for thread 3");
exit(EXIT_FAILURE);
}
if (st_thread_create(Thread4(), &thread4, 0, 0) == NULL) {
perror("st_thread_create failed for thread 4");
exit(EXIT_FAILURE);
}
return 0;
}
void *Thread1()
{
int c;
while (1)
{
c=fgetc(stdin);
c_deposit(buffer1,c);
if(c==EOF)
{
break;
}
}
st_thread_exit(NULL);
return NULL;
}
void *Thread2(void *state)
{
int c;
while(1)
{
c=c_remove(buffer1);
if(c==EOF)
{
break;
}
if(c=='\n')
{
c=' ';
}
c_deposit(buffer2,c);
}
st_thread_exit(NULL);
return NULL;
}
void *Thread3(void *state)
{
int c;
while(1)
{
c=c_remove(buffer2);
if(c==EOF)
{
break;
}
if(c=='*' && c_remove(buffer2)=='*')
{
c_remove(buffer2);
c='^';
c_deposit(buffer3,c);
}
else
{
c_deposit(buffer3,c);
}
}
st_thread_exit(NULL);
return NULL;
}
void *Thread4(void *state)
{
int counter=0;
int c;
char output[MAX_CHARS];
output[MAX_CHARS-1]='\0';
while(1)
{
c=c_remove(buffer3);
if(c==EOF)
{
break;
}
else
{
output[counter]=c;
if(counter==80)
{
printf("%s",output);
counter=-1;
memset(output,'\0',BUFF_SIZE);
}
counter++;
}
}
st_thread_exit(NULL);
return NULL;
}
Buffer.c:
#include <stdio.h>
#include <stdlib.h>
#include "semaphore.h"
#include "buffer.h"
buffer *init_buffer(int size)
{
buffer *new_Buffer;
new_Buffer=malloc((sizeof(buffer)));
createSem(new_Buffer->emptyBuffer, size);
new_Buffer->emptyBuffer=malloc(sizeof(semaphore));
createSem(new_Buffer->fullBuffer, 0);
new_Buffer->fullBuffer=malloc(sizeof(semaphore));
new_Buffer->chars=malloc(sizeof(char)*size);
new_Buffer->size=size;
new_Buffer->nextIn=0;
new_Buffer->nextOut=0;
return new_Buffer;
}
void c_deposit(buffer *buffer, char c)
{
down(buffer->emptyBuffer);
buffer->chars[buffer->nextIn]=c;
buffer->nextIn=(buffer->nextIn+1)%buffer->size;
up(buffer->fullBuffer);
}
int c_remove(buffer *buffer)
{
int c;
down(buffer->fullBuffer);
c=buffer->chars[buffer->nextOut];
buffer->nextOut=(buffer->nextOut+1)%buffer->size;
up(buffer->emptyBuffer);
return c;
}
buffer.h:
#include <stdio.h>
#include "semaphore.h"
typedef struct{
semaphore emptyBuffer;
semaphore fullBuffer;
int nextIn;
int nextOut;
int size;
char *chars;
}buffer;
void c_deposit(buffer *buffer, char c);
int c_remove(buffer *buffer);
buffer *init_buffer(int size);

Change
gcc Main.c semaphore.o -L. -lst -o test
To
gcc Main.c semaphore.o buffer.c -L. -lst -o test

I was told you don't need to include a reference to a ".c" file as long as you reference its ".h" file.
This is incorrect. Every .c source file needs to be compiled to a .o object file. The object files are then linked together to form the final binary. You can let gcc do this for you by simply specifying all of your .c files on your gcc command line.
The only thing #include "buffer.h" does, is copy the contents of that .h file into the current .c file. You do this so the .c file knows about all of the types referenced, and the prototypes of the functions you'll be calling, (so it can generate the correct code for the call).
In this case, you simple need to add buffer.c to your gcc command line.

try
gcc Main.c buffer.c semaphore.o -L. -lst -o test
you might want to add a prototype for init_buffer to buffer.h:
buffer *init_buffer(int size);

Related

Compile time error when using struct in other c file

I am using a structure that I defined in main.h and now using it in stack.c. In my main.h I have defined struct details and struct library. When I access them in stack.c I get the following error. When I am running a single main.c file then it's having no issues, so, I assume the issue lies in the stack.c or stack.h file.
Undefined symbols for architecture x86_64:
"_details", referenced from:
_main in main.o
_library_details in main.o
_push in stack.o
(maybe you meant: _library_details)
"_library", referenced from:
_main in main.o
_library_details in main.o
_push in stack.o
(maybe you meant: _library_details)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation
Here are my code snippets:
main.c
// write code below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
void library_details(void);
FILE *fp;
int choice, indexer = 1;
//details_struct details[maxsize];
//library_struct library[maxsize];
int main(void)
{
// library = malloc(sizeof(library_struct) * 2);
fp = fopen("input.txt","r");
library_details();
for (int i = 1; i < indexer; i++)
{
if(library[i].type == is_book)
{
printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
}
else if(library[i].type == is_article)
{
printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
}
}
fclose(fp);
//free(library);
return 0;
}
main.h
#ifndef __MAIN_H_
#define __MAIN_H_
enum book_type {is_book, is_article};
typedef struct library_struct
{
enum book_type type;
void *item;
}library_struct;
typedef struct details_struct
{
char title[50];
int pages;
}details_struct;
// external variables
extern int choice, indexer;
extern details_struct details[100];
extern library_struct library[100];
// library details
void library_details(void);
#endif // __MAIN_H_
stack.c
// stack.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
#include "main.h"
//functions declarations
void push(void);
stack books_stack[100];
int top = 0;
int stack_main(void)
{
return 0;
}
void push()
{
if(top >= 99)
{
printf("Stack Overflow\n");
exit(-1);
}
else
{
if(library[top].type == is_book)
{
strcpy(books_stack[top].s_title, details[top].title);
books_stack[top].s_pages = details[top].pages;
}
}
}
stack.h
#ifndef __STACK_H_
#define __STACK_H_
typedef struct stack
{
char s_title[50];
int s_pages;
}stack;
// functions declaration
void push();
#endif // __STACK_H_
Is there any issue with struct declarations?
Haven't used C in a while so I can't straight answer your question, but I made your code compile. However the compiled program has a C runtime abort. (Potentially some exception or something...) Examine this and consider the diff... in h you never instantiate, you declare, in c you instantiate your declaration. I don't know why you were doing extern + trying to instantiate... The other answers noted a most of the areas I messed with.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
FILE *fp;
int choice, indexer = 1;
int maxsize = 50;
details_struct details[100];
library_struct library[100];
void library_details(void)
{
return;
}
int main(void)
{
// library = malloc(sizeof(library_struct) * 2);
fp = fopen("input.txt","r");
library_details();
for (int i = 1; i < indexer; i++)
{
if(library[i].type == is_book)
{
printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
}
else if(library[i].type == is_article)
{
printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
}
}
fclose(fp);
//free(library);
return 0;
}
main.h
#ifndef __MAIN_H_
#define __MAIN_H_
enum book_type {is_book, is_article};
typedef struct library_struct
{
enum book_type type;
void *item;
} library_struct;
typedef struct details_struct
{
char title[50];
int pages;
} details_struct;
// external variables
extern int choice, indexer;
details_struct details[];
library_struct library[];
// library details
void library_details(void);
#endif // __MAIN_H_
stack.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
//functions declarations
void push(void);
stack books_stack[100];
int top = 0;
int stack_main(void)
{
return 0;
}
void push() {
if (top >= 99) {
printf("Stack Overflow\n");
exit(-1);
} else {
if (library[top].type == is_book) {
strcpy(books_stack[top].s_title, details[top].title);
books_stack[top].s_pages = details[top].pages;
}
}
stack.h
#ifndef __STACK_H_
#define __STACK_H_
#include "main.h"
typedef struct stack
{
char s_title[50];
int s_pages;
} stack;
// functions declaration
void push();
#endif // __STACK_H_
}
library an library_details are not exist in your code
You declare the function in main.h, but is not in in main.c
And, with library[], you are using but is not declared
You seem to have commented out the variable declarations:
//details_struct details[maxsize];
//library_struct library[maxsize];
So, neither details nor library are defined, and this is what the compiler is complaining about.

Makefile in C (ubuntu) multiple definition

I am learning c and trying to build using makefile. I am stuck on the following error and don't know what to do next.
the build command is
gcc -o logfind logfind.o cmdargutils.o filesystem_utils.o file_utils.o strutils.o
If I need both file_utils.o and cmdargutils.o but if I add both I get the following error.
error screenshot
ERROR
file_utils.o:(.rodata+0x0): multiple definition of `MAX_LINE'
logfind.o:(.rodata+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'logfind' failed
make: *** [logfind] Error 1
The source is:
Makefile
logfind: clean logfind.o
gcc -o logfind logfind.o cmdargutils.o filesystem_utils.o file_utils.o strutils.o
logfind.o: logfind.c cmdargutils.o file_utils.o filesystem_utils.o strutils.o error_codes.h
gcc -c logfind.c
cmdargutils.o: cmdargutils.c cmdargutils.h
gcc -c cmdargutils.c
file_utils.o: file_utils.c file_utils.h
gcc -c file_utils.c
filesystem_utils.o: filesystem_utils.c filesystem_utils.h
gcc -c filesystem_utils.c
strutils.o: strutils.c strutils.h
gcc -c strutils.c
clean:
rm -f *.o logfind
cmdargutils.h
#ifndef CMD_ARG_UTILS
#define CMD_ARG_UTILS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include "error_codes.h"
#include "strutils.h"
struct Argument {
bool is_and_operation;
int count;
char **search_terms;
};
struct Argument *argument_create(int argc, char **argv, int start, bool is_and_operation);
void argument_destroy(struct Argument *argument);
struct Argument *parse_arguments(int argc, char **argv);
#endif
error_codes.h
#ifndef ERROR_CODES
#define ERROR_CODES
enum error_codes {
MEMORY_ERROR,
INPUT_ERROR
};
#endif
file_utils.h
#ifndef FILE_UTILS
#define FILE_UTILS
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "cmdargutils.h"
const size_t MAX_LINE = 1024;
bool is_match(char *, struct Argument *);
bool scan_file(char *, struct Argument *);
#endif
filesystem_utils.h
#ifndef FILESYSTEM_UTILS
#define FILESYSTEM_UTILS
#include <glob.h>
#include <string.h>
#include "strutils.h"
struct SearchFiles {
int count;
char **paths;
};
struct SearchFiles *search_files_create(int count, char** paths);
void search_files_destroy(struct SearchFiles *search_files);
struct SearchFiles *scan_directory(char *directory_path, char *pattern);
#endif
strutils.h
#ifndef STRUTILS
#define STRUTILS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error_codes.h"
char *strdup(const char *source);
char **copy_string_array(char **source, int start, int end);
#endif
logfind.c
#include <stdio.h>
#include <stdlib.h>
#include <glob.h>
#include "cmdargutils.h"
#include "filesystem_utils.h"
#include "file_utils.h"
int main(int argc, char **argv) {
struct Argument *argument = parse_arguments(argc, argv);
int i = 0;
struct SearchFiles *search_files = scan_directory(".", "*.*");
for(i = 0; i < search_files->count; i++) {
scan_file(search_files->paths[i], argument);
}
search_files_destroy(search_files);
argument_destroy(argument);
return 0;
}
cmdargutils.c
#include "cmdargutils.h"
struct Argument *argument_create(int argc, char **argv, int start, bool is_and_operation){
struct Argument *argument = (struct Argument *)malloc(sizeof(struct Argument));
if(!argument) {
printf("Could not initialize arguments.\n");
exit(MEMORY_ERROR);
}
argument->count = argc - start;
argument->is_and_operation = is_and_operation;
argument->search_terms = copy_string_array(argv, start, argc);
return argument;
}
void argument_destroy(struct Argument *argument){
int i = 0;
for(i = 0; i < argument->count; i++) {
free(argument->search_terms[i]);
}
free(argument->search_terms);
free(argument);
argument = NULL;
}
struct Argument *parse_arguments(int argc, char **argv) {
struct Argument *argument = NULL;
bool is_and_operation = true;
int start = 0;
if(argc < 2) {
printf("Not enough arguments\n");
exit(INPUT_ERROR);
}
char *operation = argv[1];
if(strcmp(operation, "-o") == 0) {
is_and_operation = false;
if(argc < 3) {
printf("Not enough arguments\n");
exit(INPUT_ERROR);
}
}
start = is_and_operation ? 1 : 2;
argument = argument_create(argc, argv, start, is_and_operation);
return argument;
}
file_utils.c
#include "file_utils.h"
bool is_match(char *line, struct Argument *argument) {
int i = 0;
bool isMatch = false;
for(i = 0; i < argument->count; i++) {
char *found = strcasestr(line, argument->search_terms[i]);
if(!found) {
if(argument->is_and_operation) {
isMatch = false;
break;
} else {
continue;
}
} else {
isMatch = true;
if(argument->is_and_operation) {
continue;
} else {
break;
}
}
}
return isMatch;
}
bool scan_file(char *path, struct Argument *argument) {
FILE *file = fopen(path, "r");
int line_number = 0;
char *line = malloc(MAX_LINE);
while(fgets(line, MAX_LINE - 1, file)!= NULL) {
++line_number;
if(is_match(line, argument)) {
printf("%s:%d\n", path, line_number);
printf("\t%s\n", line);
}
}
free(line);
fclose(file);
}
filesystem_utils.c
#include "filesystem_utils.h"
struct SearchFiles *search_files_create(int count, char** paths) {
struct SearchFiles *search_files = (struct SearchFiles *)malloc(sizeof(struct SearchFiles));
search_files->count = count;
search_files->paths = copy_string_array(paths, 0, count);
return search_files;
}
void search_files_destroy(struct SearchFiles *search_files) {
int i = 0;
for(i = 0; i < search_files->count; i++) {
free(search_files->paths[i]);
}
free(search_files->paths);
free(search_files);
search_files = NULL;
}
struct SearchFiles *scan_directory(char *directory_path, char *pattern) {
glob_t globbuf;
int error = glob(pattern, GLOB_MARK, NULL, &globbuf);
if(!error) {
struct SearchFiles *search_files = search_files_create(globbuf.gl_pathc, globbuf.gl_pathv);
globfree(&globbuf);
return search_files;
}
return NULL;
}
strutils.c
#include "strutils.h"
char *strdup(const char *source) {
char *dest = malloc(strlen(source) + 1);
if(!dest) {
printf("Memory allocation error\n");
exit(MEMORY_ERROR);
}
strcpy(dest, source);
return dest;
}
char **copy_string_array(char **source, int start, int end) {
char **dest = (char **)malloc(sizeof(char *) * (end - start));
int di = 0;
int si = start;
for(di = 0, si = start; si < end;
si++, di++) {
dest[di] = strdup(source[si]);
}
return dest;
}
read documentation!
First, take a few hours to read documentation of GNU make, and read how to invoke GCC. You also need to understand more about the preprocessor, so read documentation of cpp. You want to take advantage of builtin GNU make rules (so run make -p to understand them) and variables. See also this answer. You could use remake (as remake -x) to debug your Makefile. You apparently don't understand how make and how gcc should be used, so you need to read more. Read also a C tutorial, look into some C reference, and glance when needed into the C11 standard n1570. Of course, read the documentation of every function you use (e.g. printf(3) etc..). For Linux system programming, read a book like ALP and relevant man pages from syscalls(2) and intro(3) etc...
Then read How to debug small programs. You certainly want to compile with all warnings and debug info.
a better Makefile
You might try something like:
# a better Makefile
# your C compiler
CC= gcc
# the verbose remove
RM= rm -vf
# your C compilation flags
CFLAGS= -Wall -Wextra -g
# your C source files
MY_CSOURCES= logfind.c cmdargutils.c filesystem_utils.c file_utils.c strutils.c
# the corresponding object files
MY_OBJECTS= $(patsubst %.c, %.o, $(MY_CSOURCES))
# the conventional phony targets
.PHONY: all clean
# the only program is for the default target all
all: logfind
logfind: $(MY_OBJECTS)
$(LINK.c) $< -o $#
# cleaning the mess
clean:
$(RM) logfind *.o *~
Of course, you need dependencies for object files on header files. You could compute them automatically, but it is simpler to explicit them, so add something like:
strutils.o: strutils.c strutils.h
and so on for each other object files.
BTW my HelloWorld/ directory on github is a tutorial example for using make
your multiple definition bug
You are getting multiple definition of MAX_LINE because it is defined in a header file included by several translation units, hence several translation units define it.
So either make it a preprocessor constant #define MAX_LINE 1024 in your header file_utils.h, or put there only a declaration like extern const int MAX_LINE; and define it only once in a single translation unit, as const int MAX_LINE=1024; in file_utils.c
general hints
I strongly recommend doing some iterative and incremental development: code only one or two dozen lines at once, then compile them, improve them to get no warnings, debug them with the GDB debugger and test them. At last repeat all this till satisfied. I do recommend using also a version control system (like git) even for school homework.
You might want to use valgrind to hunt memory leaks and other dynamic memory allocation bugs.
You could also use some static source analyzer like clang-analyzer or even Frama-C.
Once your program is debugged, you might add optimization flags like -O2 into your CFLAGS (in particular if you benchmark it with time(1)).
You could be interested by ntfw(3).

Realloc using extern

Hi im trying to figure out how to use realloc. I have made a small test project that im trying to malloc for the creation of the first element in main, followed by adding a number to that location then reallocating the array to hold one more element.
Main.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int i =0;
int *fileTest = (int*) malloc(sizeof(char * ));
int amtFiles=0;
for(i=0;i<3;i++){
parseInput(fileTest , amtFiles);
printf("%d", fileTest[1]);
}
}
parse.c
#include <stdlib.h>
#include "stddef.h";
#include <stdlib.h>
extern int parseInput(int *fileTest,int amtFiles){
printf("enter number");
scanf("%d",amtFiles);
fileTest = realloc(fileTest, (amtFiles * sizeof(char *)));
}
makefile
CC = gcc
CC_FLAGS = -g -ansi -pedantic -Wall -w
FILES = main.c parse.c
OUT_EXE = Test2
build: $(FILES)
$(CC) $(CC_FLAGS) -o $(OUT_EXE) $(FILES)
clean:
rm -f *.o core *.exe *~
rebuild: clean build
C is pass by value. You should return the pointer value. Otherwise the original one is unchanged. So from parseInput return the pointer or pass address of the variable and change it accordingly (not shown in example).
While reallocating use another pointer variable other than the original one, in case of failure you don't lose reference to the old memory.
Don't print uninitialized value. (in main()).
Don't cast the return value of malloc.
When printing a pointer do this printf("%p",(void*)fileTest[1]);.
Also you should put the extern declaration in main.c. You have passed incorrect number of arguments to the parseInput function. The code didn' compile.
Then after correcting the input - if you try then you might get segmentation fault or some similar error.
I have tried demonstrating something over here. The naming can be much more better. I have tried to keep the general aspects of what you have tried. Multiple source file with realloc used and tested, working with pointers etc.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "myheader.h"
int main(void)
{
int *fileTest = NULL;
int amtFiles;
int weTried = 2;
while(weTried --> 0){
printf("%s\n", "Enter the array size.\n");
if( scanf("%d",&amtFiles) != 1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
else if( amtFiles <= 0){
fprintf(stderr, "%s\n", "Enter positive integral value");
exit(1);
}
fileTest = parseInput(fileTest, amtFiles);
if( fileTest == NULL){
fprintf(stderr, "%s\n","Realloc failed." );
exit(1);
}
for(int i = 0; i < amtFiles; i++){
printf("[%d]\n",fileTest[i]);
}
}
return 0;
}
parse.c
#include <stdlib.h>
#include <stdio.h>
#include "myheader.h"
int* parseInput(int *fileTest,int amtFiles)
{
if( amtFiles <= 0){
fprintf(stderr, "%s\n", "Error in number of inputs");
exit(1);
}
int *t = realloc(fileTest, (amtFiles * sizeof * t));
if( t == NULL ){
fprintf(stderr, "%s\n", "Execution exception");
return NULL;
}
fileTest = t;
for(int i = 0; i < amtFiles; i++){
fileTest[i] = 2017+i;
}
return fileTest;
}
myheader.h
extern int* parseInput(int *,int );
Compiled and run
gcc -Wall -Wextra -Werror main.c parse.c
./a.out

undefined reference.. linker command failed with exit code 1

I want to create a shell file using the c language programming. I have this scheleton given already by the professor, but wen I try to executed I have this error and I have this problem
the myshell.c file (and this file is the one that I have to modify and execute)
/* RCS information: $Id: myshell.c,v 1.2 2006/04/05 22:46:33 elm Exp $ */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
extern char **getcmdstring(char *cmd);
int main(void) {
int i;
char **args;
char cmd[4096];
while(1) {
printf("$ ");
fgets(cmd,4096,stdin);
args = getcmdstring(cmd);
for(i = 0; args[i] != NULL; i++) {
printf("Argument %d: %s\n", i, args[i]);
}
}
}
and the shell.l file
/* RCS information: $Id: shell.l,v 1.1 2006/04/05 22:46:33 elm Exp $ */
#include <stdio.h>
#include <strings.h>
#include <string.h>
int _numargs = 200;
char *_args[200];
int _argcount = 0;
char *strdup(const char *);
%}
WORD [a-zA-Z0-9\/\.-]+
SPECIAL [()><|&;]
%%
_argcount = 0; _args[0] = NULL;
{WORD}|{SPECIAL} {
if(_argcount < _numargs-1) {
_args[_argcount++] = (char *)strdup(yytext);
_args[_argcount] = NULL;
}
}
\n return (int)_args;
[ \t]+
.
%%
char **getcmdstring(char *cmd) {
char **ret;
yy_scan_string(cmd);
ret = (char **)yylex();
yy_delete_buffer(YY_CURRENT_BUFFER);
return ret;
}
The missing function is included in the shell.l source. This is a source for a lexical analyzer. You need to build the shell.o object file from shell.l.
This can be done by creating the C source
flex -o shell.c shell.l
and then compiling
clang shell.c myshell.c -o myshell -ll

Thread error while compiling the Xml parser in C?

[root#localhost mxml-2.7]# gcc -o xml XmlParser1.c -lmxml
XmlParser1.c: In function ‘main’:
XmlParser1.c:63: warning: assignment discards qualifiers from pointer target type
/usr/local/lib/libmxml.so: undefined reference to `pthread_key_create'
/usr/local/lib/libmxml.so: undefined reference to `pthread_once'
/usr/local/lib/libmxml.so: undefined reference to `pthread_getspecific'
/usr/local/lib/libmxml.so: undefined reference to `pthread_key_delete'
/usr/local/lib/libmxml.so: undefined reference to `pthread_setspecific'
collect2: ld returned 1 exit status
Following error occurred while compiling the XmlParser1.c.
XmlParser1.c:
#include <stdio.h>
#include "mxml.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define MAX_SIZE 25
static mxml_node_t *xml;
static mxml_node_t *str;
static mxml_node_t *DataSet;
static mxml_node_t *Table;
static mxml_node_t *IsAuthenticated;
static mxml_node_t *AuthenticationDate;
static mxml_node_t *Response;
int main()
{
int fd = 0;
char *Result=NULL;
const char *NewResult=NULL;
mxml_node_t *tree;
mxml_node_t *data;
const char *type = NULL;
FILE *fp = fopen("/home/suneet/mxml-2.7/Sample/main.xml", "r") ;
if (fp == NULL)
{
fclose(fp);
}
else
{
fseek (fp , 0, SEEK_END);
long settings_size = ftell (fp);
rewind (fp);
if (settings_size > 0)
{
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
fclose(fp);
printf("step 1\n");
data = mxmlFindElement(Table, tree, "diffgr:id", NULL, NULL, MXML_DESCEND);
Result = mxmlElementGetAttr(data,"diffgr:id");
printf("diffgr:id:%s\n",(Result == NULL)?"NULL":Result);
mxmlDelete(data);
mxmlDelete(tree);
}
}
return 0;
}
while i am trying to go with the steps given in http://minixml.org/; parse accordingly the xml file there is certain error "undefined error to threads for dynamic library libxml.so.".
Please guide me so that i can successfully parse the xml file.
You need to link with the pthread library using the -pthread option.
gcc -o xml XmlParser1.c -lmxml -pthread
You need to include pthread in you code.
add this line at the beginning of your file
#include<pthread.h>

Resources