Skip to content

Instantly share code, notes, and snippets.

@FFY00
Last active June 12, 2019 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FFY00/26a3380232dcc4826c0477e6be576780 to your computer and use it in GitHub Desktop.
Save FFY00/26a3380232dcc4826c0477e6be576780 to your computer and use it in GitHub Desktop.
My resolution of the S.O. 2nd Practical Test
package "is_ascii"
version "0.0.1"
purpose "Find if a file contains valid ASCII data"
description "This utility checks if the contents of a file are valid acording to the ASCII table."
option "filename" f "File to read"
string yes
option "verbose" v "Verbose output"
no
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include "arguments.h"
#define CMDLINE_PARSER_ERROR 1
#define FILE_ERROR 2
#define logv(...) \
if(args_info.verbose_given) printf(__VA_ARGS__);
extern int errno;
int main(int argc, char** argv)
{
struct gengetopt_args_info args_info;
if (cmdline_parser(argc, argv, &args_info) != 0)
{
fprintf(stderr, "Error parsing command line arguments.");
return CMDLINE_PARSER_ERROR;
}
logv("[Verbose mode]\n");
/* filename is required
verbose is optional */
/* open file */
int fd = open(args_info.filename_arg, O_RDONLY);
if(fd == -1)
{
fprintf(stderr, "Can't open file '%s' (%s)\n", args_info.filename_arg, strerror(errno));
cmdline_parser_free(&args_info);
return FILE_ERROR;
}
/* all good - now let's start verifying the file */
uint8_t byte;
unsigned int count = 0;
int ret;
for(unsigned int i = 0;; ++i)
{
ret = read(fd, &byte, sizeof(byte));
/* check for error reading the file */
if(ret == -1)
{
perror(argv[0]);
cmdline_parser_free(&args_info);
return FILE_ERROR;
}
if(ret == sizeof(byte))
{
if(byte > 127)
{
++count;
logv("Byte %u:%u (>127)\n", i, byte);
}
} else
/* no data read - we arrived at the end */
break;
}
logv("Summary: %u bytes not ASCII\n", count);
if(count == 0)
printf("'%s' is ASCII\n", args_info.filename_arg);
else
printf("'%s' is NOT ASCII\n", args_info.filename_arg);
if(close(fd) == -1)
{
perror(argv[0]);
cmdline_parser_free(&args_info);
return FILE_ERROR;
}
cmdline_parser_free(&args_info);
return 0;
}
CFLAGS :=$(CFLAGS) -Wall -Wextra -std=c99 -pedantic -ggdb
LDFLAGS :=$(LDFLAGS) #-lm -pthread
PROGRAM =is_ASCII
SRCDIR =source
INCDIR =include
OUTDIR =out
SRCS :=$(wildcard $(SRCDIR)/*.c)
OBJS :=$(SRCS:$(SRCDIR)/%.c=$(OUTDIR)/%.o)
CFLAGS :=$(CFLAGS) -I$(INCDIR) -I$(OUTDIR)
all: link
link: $(OUTDIR) gengetopt $(OBJS)
$(CC) $(LDFLAGS) $(OUTDIR)/arguments.o $(OBJS) -o $(OUTDIR)/$(PROGRAM)
$(OUTDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $(@:$(OUTDIR)/%.o=$(SRCDIR)/%.c) -o $@
gengetopt:
gengetopt --file-name arguments --output-dir $(OUTDIR) --unamed-opts -i $(SRCDIR)/arguments.ggo
$(CC) $(CFLAGS) -c $(OUTDIR)/arguments.c -o $(OUTDIR)/arguments.o
$(OUTDIR):
mkdir -p $(OUTDIR)
clean:
rm -rf $(OUTDIR)
.PHONY: all link clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment