C: change phone-number to exercism V3

This commit is contained in:
2021-09-03 15:51:40 +02:00
parent 77a8072c73
commit 33cc1343cb
6 changed files with 33 additions and 182 deletions

View File

@@ -27,6 +27,10 @@
default: all
ALLSOURCES=$(wildcard ./*.c)
TESTSOURCES=$(wildcard ./test_*.c)
SRC=$(filter-out $(TESTSOURCES),$(ALLSOURCES))
include makefile
all: CFLAGS+=-DTESTALL
@@ -48,5 +52,6 @@ unitdebug: CFLAGS+=-DDEBUG
unitdebug: clean unit
unit: CFLAGS+=-DUNIT_TEST
unit: src/*.c src/*.h
$(CC) $(CFLAGS) src/*.c -o tests.out $(LIBS)
unit: SOURCES=$(wildcard ./*.c)
unit: *.c *.h
$(CC) $(CFLAGS) $(SRC) -o tests.out $(LIBS)

View File

@@ -1,5 +1,10 @@
# Phone Number
Welcome to Phone Number on Exercism's C Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Clean up user-entered phone numbers so that they can be sent SMS messages.
The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`.
@@ -28,40 +33,24 @@ should all produce the output
**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.
## Getting Started
Make sure you have read the "Guides" section of the
[C track][c-track] on the Exercism site. This covers
the basic information on setting up the development environment expected
by the exercises.
## Passing the Tests
Get the first test compiling, linking and passing by following the [three
rules of test-driven development][3-tdd-rules].
The included makefile can be used to create and run the tests using the `test`
task.
make test
Create just the functions you need to satisfy any compiler errors and get the
test to fail. Then write just enough code to get the test to pass. Once you've
done that, move onto the next test.
As you progress through the tests, take the time to refactor your
implementation for readability and expressiveness and then go on to the next
test.
Try to use standard C99 facilities in preference to writing your own
low-level algorithms or facilities by hand.
## Source
Event Manager by JumpstartLab [http://tutorials.jumpstartlab.com/projects/eventmanager.html](http://tutorials.jumpstartlab.com/projects/eventmanager.html)
### Created by
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
- @RealBarrettBrown
[c-track]: https://exercism.io/my/tracks/c
[3-tdd-rules]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
### Contributed to by
- @bcc32
- @Gamecock
- @gea-migration
- @h-3-0
- @mikewalker
- @patricksjackson
- @QLaille
- @ryanplusplus
- @wolf99
### Based on
Event Manager by JumpstartLab - http://tutorials.jumpstartlab.com/projects/eventmanager.html

View File

@@ -11,7 +11,6 @@ CFLAGS += -Wextra
CFLAGS += -pedantic
CFLAGS += -Werror
CFLAGS += -Wmissing-declarations
CFLAGS += -Wimplicit-fallthrough
CFLAGS += -DUNITY_SUPPORT_64
ASANFLAGS = -fsanitize=address
@@ -23,9 +22,9 @@ test: tests.out
@./tests.out
.PHONY: memcheck
memcheck: test/*.c src/*.c src/*.h
memcheck: ./*.c ./*.h
@echo Compiling $@
@$(CC) $(ASANFLAGS) $(CFLAGS) src/*.c test/vendor/unity.c test/*.c -o memcheck.out $(LIBS)
@$(CC) $(ASANFLAGS) $(CFLAGS) test-framework/unity.c ./*.c -o memcheck.out $(LIBS)
@./memcheck.out
@echo "Memory check passed"
@@ -33,6 +32,6 @@ memcheck: test/*.c src/*.c src/*.h
clean:
rm -rf *.o *.out *.out.dSYM
tests.out: test/*.c src/*.c src/*.h
tests.out: ./*.c ./*.h
@echo Compiling $@
$(CC) $(CFLAGS) src/*.c test/vendor/unity.c test/*.c -o tests.out $(LIBS)
@$(CC) $(CFLAGS) test-framework/unity.c ./*.c -o tests.out $(LIBS)

View File

@@ -1,80 +0,0 @@
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdint.h>
#include "phone_number.h"
#define LEN_NUM 10
#define LPAREN '('
/* this version is likely not very stable, due to poor scanf() capabilities
* I made it to offer an option to traditional strtok() or manual string
* parsing.
*/
char *phone_number_clean(const char *input)
{
char *scan="%m[+(0-9]%*[()-. ]%m[0-9]%*[()-. ]%m[0-9]%*[-. ]%m[0-9]";
char *sn[4];
uint64_t num[4];
uint64_t *p = &num[0];
int nmatch;
char *res;
if (!(res = malloc(LEN_NUM+1)))
return NULL;
memset(res, '0', LEN_NUM);
*(res+LEN_NUM) = 0;
nmatch = sscanf(input, scan, &sn[0], &sn[1], &sn[2], &sn[3]);
for (int i=0; i<nmatch; ++i) {
*(p+i) = atol(*sn[i] == LPAREN? sn[i]+1: sn[i]);
free(sn[i]);
}
switch (nmatch) {
case 2:
case 0:
return res;
case 1:
if (*p > 10000000000) /* 1 000 000 0000 */
*p -= 10000000000;
if (*p > 9999999999 || /* 999 999 9999 */
*p < 2000000000) /* 200 000 0000 */
return res;
break;
case 4: /* area */
if (*p != 1)
return res;
p++;
fallthrough; /* only gcc>=7 & clang>=12 */
case 3: /* last 3 numbers */
if (*p < 200 || *p > 999 ||
*(p+1) < 200 || *(p+1) > 999 ||
*(p+2) > 9999)
return res;
break;
}
snprintf(res, LEN_NUM+1, "%ld%ld%ld", *p, *(p+1), *(p+2));
return res;
}
/* See GNUmakefile below for explanation
* https://github.com/braoult/exercism/blob/master/c/templates/GNUmakefile
*/
#ifdef UNIT_TEST
int main(int ac, char **av)
{
int arg;
char *res;
for (arg=1; arg<ac; ++arg) {
res=phone_number_clean(av[arg]);
printf("orig = [%s]\n", av[arg]);
printf("\t-> [%s]\n", res);
free(res);
}
}
#endif

View File

@@ -1,10 +0,0 @@
#ifndef PHONE_NUMBER_H
#define PHONE_NUMBER_H
#include "br-common.h"
#define NUMBER_LENGTH 10
char *phone_number_clean(const char *input);
#endif

View File

@@ -1,52 +0,0 @@
# The original 'makefile' has a flaw:
# 1) it overrides CFLAGS
# 2) it does not pass extra "FLAGS" to $(CC) that could come from environment
#
# It means :
# - we need to edit 'makefile' for different builds (DEBUG, etc...), which is
# not practical at all.
# - Also, it does not allow to run all tests without editing the test source
# code.
#
# To use this makefile (GNU make only):
# 1) copy it into exercise directory
# 2) add ex.h to exercise include file
# 3) add ex.c to exercise source code, and create a suitable main function
# 4) use make with one of the following targets :
# all: compile and run all predefined tests.
# nowarn: compile with no -Werror, and run all predefined tests
# debug: compile with -DDEBUG and run all predefined tests
# mem: perform memcheck with all tests enabled
# unit: build standalone (unit) bimary
# unitnowarn: build standalone (unit) binary with -Werror disabled
# unitdebug: build standalone binary with -DDEBUG
#
# Original 'makefile' targets can be used (test, memcheck, clean, ...)
.PHONY: default all nowarn debug mem unit unitnowarn unitdebug standalone
default: all
include makefile
all: CFLAGS+=-DTESTALL
all: clean test
nowarn: CFLAGS:=$(filter-out -Werror,$(CFLAGS))
nowarn: clean all
debug: CFLAGS+=-DDEBUG
debug: all
mem: CFLAGS+=-DTESTALL
mem: clean memcheck
unitnowarn: CFLAGS:=$(filter-out -Werror,$(CFLAGS))
unitnowarn: clean unit
unitdebug: CFLAGS+=-DDEBUG
unitdebug: clean unit
unit: CFLAGS+=-DUNIT_TEST
unit: src/*.c src/*.h
$(CC) $(CFLAGS) src/*.c -o tests.out $(LIBS)