First!
This commit is contained in:
commit
3ccf5d377d
|
@ -0,0 +1,50 @@
|
|||
BIN = vcf2cnt
|
||||
VERSION = 1.0
|
||||
|
||||
PREFIX = /usr/local
|
||||
|
||||
INCS =
|
||||
LIBS =
|
||||
|
||||
CPPFLAGS_VCF2CNT = -DVERSION=\"${VERSION}\" ${CPPFLAGS}
|
||||
# debug
|
||||
#CFLAGS_VCF2CNT = -ggdb -ansi -pedantic ${INCS} ${CPPFLAGS_VCF2CNT} ${CLAGS}
|
||||
CFLAGS_VCF2CNT = -Os -ansi -pedantic ${INCS} ${CPPFLAGS_VCF2CNT} ${CFLAGS}
|
||||
LDFLAGS_VCF2CNT = ${LIBS} ${LDFLAGS}
|
||||
|
||||
SRC = vcf2cnt.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: options vcf2cnt
|
||||
|
||||
options:
|
||||
@echo vcf2cnt build options:
|
||||
@echo "CFLAGS = ${CFLAGS_VCF2CNT}"
|
||||
@echo "LDFLAGS = ${LDFLAGS_VCF2CNT}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS_VCF2CNT} -c $< -o $@
|
||||
|
||||
${BIN}: ${OBJ}
|
||||
${CC} -o ${BIN} ${OBJ} ${LDFLAGS_VCF2CNT}
|
||||
|
||||
clean:
|
||||
rm -f ${BIN} ${BIN}-${VERSION}.tar.gz *.o
|
||||
|
||||
dist: clean
|
||||
mkdir ${BIN}-${VERSION}
|
||||
cp -R ${SRC} LICENSE Makefile README ${BIN}-${VERSION}
|
||||
tar -cf ${BIN}-${VERSION}.tar ${BIN}-${VERSION}
|
||||
gzip ${BIN}-${VERSION}.tar
|
||||
rm -fr ${BIN}-${VERSION}
|
||||
|
||||
install: ${BIN}
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/${BIN}
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/${BIN}
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
read -p 'Nome: ' name
|
||||
read -p 'Cognome: ' surname
|
||||
read -p 'Cellulare: ' cellphone
|
||||
read -p 'Indirizzo: ' address
|
||||
read -p 'Email: ' email
|
||||
read -p 'Telefono: ' phone
|
||||
read -p 'XMPP: ' xmpp
|
||||
read -p 'Note: ' note
|
||||
|
||||
printf 'BEGIN:VCARD\r\n'
|
||||
printf 'VERSION:4.0\r\n'
|
||||
|
||||
printf 'N:%s;%s;;;\r\n' "$surname" "$name"
|
||||
printf 'FN:%s %s\r\n' "$name" "$surname"
|
||||
|
||||
if [ -n "$cellphone" ]; then
|
||||
printf 'TEL;TYPE=CELL:%s\r\n' "$cellphone"
|
||||
fi
|
||||
|
||||
if [ -n "$email" ]; then
|
||||
printf 'EMAIL;TYPE=HOME:%s\r\n' "$email"
|
||||
fi
|
||||
|
||||
if [ -n "$phone" ]; then
|
||||
printf 'TEL;TYPE=HOME:%s\r\n' "$phone"
|
||||
fi
|
||||
|
||||
if [ -n "$xmpp" ]; then
|
||||
printf 'IMPP;TYPE=HOME:xmpp:%s\r\n' "$xmpp"
|
||||
fi
|
||||
|
||||
if [ -n "$note" ]; then
|
||||
printf 'NOTE:%s\r\n' "$(echo "$note" | sed 's/\\/\\\\/g;s/,/\\,/g')"
|
||||
fi
|
||||
|
||||
printf 'END:VCARD\r\n'
|
|
@ -0,0 +1,545 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* macros */
|
||||
#define FBUF_SIZE 4096
|
||||
|
||||
typedef struct {
|
||||
char *address;
|
||||
char *birth_date;
|
||||
char *cellphone;
|
||||
char *email;
|
||||
char *name;
|
||||
char *note;
|
||||
char *organization;
|
||||
char *phone;
|
||||
char *surname;
|
||||
char *website;
|
||||
char *work_address;
|
||||
char *work_cellphone;
|
||||
char *work_email;
|
||||
char *work_phone;
|
||||
char *work_xmpp;
|
||||
char *xmpp;
|
||||
} Contatto;
|
||||
|
||||
/* function declarations */
|
||||
static int convert_vcard(char **contact);
|
||||
static int convert_vcard_line(Contatto *contatto, const char *line);
|
||||
static void convert_vcard_property_adr(Contatto *contatto, const char *value, const char *parameter);
|
||||
static void convert_vcard_property_email(Contatto *contatto, const char *value, const char *parameter);
|
||||
static void convert_vcard_property_n(Contatto *contatto, const char *value);
|
||||
static void convert_vcard_property_note(Contatto *contatto, const char *value);
|
||||
static void convert_vcard_property_org(Contatto *contatto, const char *value);
|
||||
static void convert_vcard_property_tel(Contatto *contatto, const char *value, const char *parameter);
|
||||
static Contatto *create_contatto(void);
|
||||
static void free_contact(char ***contact);
|
||||
static void free_contatto(Contatto *contatto);
|
||||
static void *safe_malloc(const size_t size);
|
||||
static void strcut_d(char **ds1, char **ds2, const char *src, const char s);
|
||||
static void strexp_d(char ***dst, const char *src, const char s);
|
||||
static void strncat_d(char **dst, const char *src, const size_t sz);
|
||||
static void strrmchar_d(char **src, const char r);
|
||||
|
||||
/* function implementations */
|
||||
int
|
||||
convert_vcard(char **contact)
|
||||
{
|
||||
Contatto *contatto;
|
||||
|
||||
contatto = create_contatto();
|
||||
|
||||
while (*contact != NULL) {
|
||||
convert_vcard_line(contatto, *contact);
|
||||
(contact)++;
|
||||
}
|
||||
|
||||
printf("------------------------------------------------------------------------\n");
|
||||
if (contatto->cellphone != NULL)
|
||||
printf("Cellulare: %s\n", contatto->cellphone);
|
||||
if (contatto->work_cellphone != NULL)
|
||||
printf("Cellulare di lavoro: %s\n", contatto->work_cellphone);
|
||||
if (contatto->surname != NULL)
|
||||
printf("Cognome: %s\n", contatto->surname);
|
||||
if (contatto->email != NULL)
|
||||
printf("Email: %s\n", contatto->email);
|
||||
if (contatto->work_email != NULL)
|
||||
printf("Email di lavoro: %s\n", contatto->work_email);
|
||||
if (contatto->address != NULL)
|
||||
printf("Indirizzo: %s\n", contatto->address);
|
||||
if (contatto->work_address != NULL)
|
||||
printf("Indirizzo di lavoro: %s\n", contatto->work_address);
|
||||
if (contatto->name != NULL)
|
||||
printf("Nome: %s\n", contatto->name);
|
||||
if (contatto->note != NULL)
|
||||
printf("Note: %s\n", contatto->note);
|
||||
if (contatto->organization != NULL)
|
||||
printf("Organizzazione: %s\n", contatto->organization);
|
||||
if (contatto->phone != NULL)
|
||||
printf("Telefono: %s\n", contatto->phone);
|
||||
if (contatto->work_phone != NULL)
|
||||
printf("Telefono di lavoro: %s\n", contatto->work_phone);
|
||||
|
||||
free_contatto(contatto);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
convert_vcard_line(Contatto *contatto, const char *line)
|
||||
{
|
||||
char *property, *parameter, *value, *tmp;
|
||||
|
||||
strcut_d(&property, &value, line, ':');
|
||||
tmp = safe_malloc(sizeof(char) * (strlen(property) + 1));
|
||||
strcpy(tmp, property);
|
||||
strcut_d(&property, ¶meter, tmp, ';');
|
||||
free(tmp);
|
||||
|
||||
|
||||
if (!strcmp(property, "BEGIN")) {
|
||||
if (strcmp(value, "VCARD") != 0) {
|
||||
fprintf(stderr, "Unexpected value \"%s\" for BEGIN property.\n", value);
|
||||
}
|
||||
|
||||
} else if (!strcmp(property, "VERSION")) {
|
||||
/* to do: handle different versions than 4.0 */
|
||||
|
||||
} else if (!strcmp(property, "FN")) {
|
||||
/* ignore FN property, we don't need it */
|
||||
|
||||
} else if (!strcmp(property, "N")) {
|
||||
convert_vcard_property_n(contatto, value);
|
||||
|
||||
} else if (!strcmp(property, "ADR")) {
|
||||
strrmchar_d(&value, '\\');
|
||||
convert_vcard_property_adr(contatto, value, parameter);
|
||||
|
||||
} else if (!strcmp(property, "TEL")) {
|
||||
convert_vcard_property_tel(contatto, value, parameter);
|
||||
|
||||
} else if (!strcmp(property, "EMAIL")) {
|
||||
convert_vcard_property_email(contatto, value, parameter);
|
||||
|
||||
} else if (!strcmp(property, "ORG")) {
|
||||
strrmchar_d(&value, '\\');
|
||||
convert_vcard_property_org(contatto, value);
|
||||
|
||||
} else if (!strcmp(property, "NOTE")) {
|
||||
strrmchar_d(&value, '\\');
|
||||
convert_vcard_property_note(contatto, value);
|
||||
|
||||
} else if (!strcmp(property, "END")) {
|
||||
if (strcmp(value, "VCARD") != 0) {
|
||||
fprintf(stderr, "Unexpected value \"%s\" for END property.\n", value);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Unknown property %s.\n", property);
|
||||
}
|
||||
|
||||
free(property);
|
||||
free(parameter);
|
||||
free(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_adr(Contatto *contatto, const char *value, const char *parameter)
|
||||
{
|
||||
char **dst, **tmp;
|
||||
unsigned int i, to_trim;
|
||||
size_t len;
|
||||
|
||||
tmp = NULL;
|
||||
to_trim = 0;
|
||||
|
||||
dst = strstr(parameter, "WORK") != NULL ? &contatto->work_address : &contatto->address;
|
||||
strexp_d(&tmp, value, ';');
|
||||
|
||||
if (*dst != NULL)
|
||||
free(*dst);
|
||||
*dst = safe_malloc(sizeof(char) * (strlen(value) + 1));
|
||||
strcpy(*dst, "");
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (strcmp(tmp[i], "") != 0) {
|
||||
strcat(*dst, tmp[i]);
|
||||
strcat(*dst, ", ");
|
||||
to_trim = 1;
|
||||
}
|
||||
}
|
||||
if (to_trim) {
|
||||
len = strlen(*dst);
|
||||
(*dst)[len - 1] = '\0';
|
||||
(*dst)[len - 2] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_email(Contatto *contatto, const char *value, const char *parameter)
|
||||
{
|
||||
char **dst;
|
||||
|
||||
dst = strstr(parameter, "WORK") != NULL ? &contatto->work_email : &contatto->email;
|
||||
|
||||
if (*dst != NULL)
|
||||
free(*dst);
|
||||
*dst = safe_malloc(sizeof(char) * (strlen(value) + 1));
|
||||
strcpy(*dst, value);
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_n(Contatto *contatto, const char *value)
|
||||
{
|
||||
char *tmp1, *tmp2;
|
||||
|
||||
strcut_d(&contatto->surname, &tmp1, value, ';');
|
||||
strcut_d(&contatto->name, &tmp2, tmp1, ';');
|
||||
|
||||
free(tmp1);
|
||||
free(tmp2);
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_note(Contatto *contatto, const char *value)
|
||||
{
|
||||
if (contatto->note != NULL)
|
||||
free(contatto->note);
|
||||
contatto->note = safe_malloc(sizeof(char) * (strlen(value) + 1));
|
||||
strcpy(contatto->note, value);
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_org(Contatto *contatto, const char *value)
|
||||
{
|
||||
if (contatto->organization != NULL)
|
||||
free(contatto->organization);
|
||||
contatto->organization = safe_malloc(sizeof(char) * (strlen(value) + 1));
|
||||
strcpy(contatto->organization, value);
|
||||
|
||||
/* to do: separate value components */
|
||||
}
|
||||
|
||||
void
|
||||
convert_vcard_property_tel(Contatto *contatto, const char *value, const char *parameter)
|
||||
{
|
||||
char **dst;
|
||||
|
||||
if (strstr(parameter, "CELL") != NULL)
|
||||
dst = strstr(parameter, "WORK") != NULL ? &contatto->work_cellphone : &contatto->cellphone;
|
||||
else
|
||||
dst = strstr(parameter, "WORK") != NULL ? &contatto->work_phone : &contatto->phone;
|
||||
|
||||
if (*dst != NULL)
|
||||
free(*dst);
|
||||
*dst = safe_malloc(sizeof(char) * (strlen(value) + 1));
|
||||
strcpy(*dst, value);
|
||||
}
|
||||
|
||||
Contatto *
|
||||
create_contatto(void)
|
||||
{
|
||||
Contatto *contatto;
|
||||
|
||||
contatto = safe_malloc(sizeof(Contatto));
|
||||
contatto->address = NULL;
|
||||
contatto->birth_date = NULL;
|
||||
contatto->cellphone = NULL;
|
||||
contatto->email = NULL;
|
||||
contatto->name = NULL;
|
||||
contatto->note = NULL;
|
||||
contatto->organization = NULL;
|
||||
contatto->phone = NULL;
|
||||
contatto->surname = NULL;
|
||||
contatto->website = NULL;
|
||||
contatto->work_address = NULL;
|
||||
contatto->work_cellphone = NULL;
|
||||
contatto->work_email = NULL;
|
||||
contatto->work_phone = NULL;
|
||||
contatto->work_xmpp = NULL;
|
||||
contatto->xmpp = NULL;
|
||||
|
||||
return contatto;
|
||||
}
|
||||
|
||||
void
|
||||
free_contact(char ***contact)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
if (*contact != NULL) {
|
||||
while (**contact != NULL) {
|
||||
free(**contact);
|
||||
**contact = NULL;
|
||||
(*contact)++;
|
||||
i++;
|
||||
}
|
||||
free(*contact - i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
free_contatto(Contatto *contatto)
|
||||
{
|
||||
|
||||
if (contatto->address != NULL)
|
||||
free(contatto->address);
|
||||
|
||||
if (contatto->birth_date != NULL)
|
||||
free(contatto->birth_date);
|
||||
|
||||
if (contatto->cellphone != NULL)
|
||||
free(contatto->cellphone);
|
||||
|
||||
if (contatto->email != NULL)
|
||||
free(contatto->email);
|
||||
|
||||
if (contatto->name != NULL)
|
||||
free(contatto->name);
|
||||
|
||||
if (contatto->note != NULL)
|
||||
free(contatto->note);
|
||||
|
||||
if (contatto->organization != NULL)
|
||||
free(contatto->organization);
|
||||
|
||||
if (contatto->phone != NULL)
|
||||
free(contatto->phone);
|
||||
|
||||
if (contatto->surname != NULL)
|
||||
free(contatto->surname);
|
||||
|
||||
if (contatto->website != NULL)
|
||||
free(contatto->website);
|
||||
|
||||
if (contatto->work_address != NULL)
|
||||
free(contatto->work_address);
|
||||
|
||||
if (contatto->work_cellphone != NULL)
|
||||
free(contatto->work_cellphone);
|
||||
|
||||
if (contatto->work_email != NULL)
|
||||
free(contatto->work_email);
|
||||
|
||||
if (contatto->work_phone != NULL)
|
||||
free(contatto->work_phone);
|
||||
|
||||
if (contatto->work_xmpp != NULL)
|
||||
free(contatto->work_xmpp);
|
||||
|
||||
if (contatto->xmpp != NULL)
|
||||
free(contatto->xmpp);
|
||||
|
||||
free(contatto);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *file;
|
||||
char buf[FBUF_SIZE];
|
||||
int alloc, c, found, l, n, read, x;
|
||||
char **contact, **tmp_contact;
|
||||
char *line, *part_line;
|
||||
|
||||
l = 0;
|
||||
contact = NULL;
|
||||
tmp_contact = NULL;
|
||||
line = "";
|
||||
part_line = "";
|
||||
|
||||
file = fopen(argv[1], "r");
|
||||
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "Can't open %s.\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fseek(file, 0, SEEK_SET) == -1) {
|
||||
fprintf(stderr, "Can't go to the start of %s.\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
do {
|
||||
read = fread(buf, 1, FBUF_SIZE, file);
|
||||
for (c = 0; c < FBUF_SIZE && c < read; c++) {
|
||||
found = 0;
|
||||
for (n = c + 1; n < FBUF_SIZE && n < read; n++) {
|
||||
if (n - 1 >= c && buf[n-1] == '\r' && buf[n] == '\n') {
|
||||
found = 1;
|
||||
line = safe_malloc(sizeof(char) * (n - c + strlen(part_line)));
|
||||
strcpy(line, part_line);
|
||||
if (strcmp(part_line, "") != 0)
|
||||
free(part_line);
|
||||
part_line = "";
|
||||
strncat(line, buf + c, n - c - 1);
|
||||
if (!strncmp(line, "BEGIN:VCARD", 11)) {
|
||||
free_contact(&contact);
|
||||
l = 0;
|
||||
} else if (l != 0 && l == alloc) {
|
||||
tmp_contact = safe_malloc(sizeof(char *) * (alloc * 2 + 1));
|
||||
for (x = alloc; x <= alloc * 2; x++)
|
||||
contact[x] = NULL;
|
||||
memcpy(tmp_contact, contact, sizeof(char *) * alloc);
|
||||
free_contact(&contact);
|
||||
contact = tmp_contact;
|
||||
alloc = alloc * 2;
|
||||
}
|
||||
if (l == 0) {
|
||||
alloc = 24;
|
||||
/* contact size is alloc + 1, so the last pointer is NULL */
|
||||
contact = safe_malloc(sizeof(char *) * (alloc + 1));
|
||||
for (x = 0; x <= alloc; x++)
|
||||
contact[x] = NULL;
|
||||
}
|
||||
contact[l] = safe_malloc(sizeof(char) * (strlen(line) + 1));
|
||||
strcpy(contact[l], line);
|
||||
if (!strncmp(line, "END:VCARD", 9)) {
|
||||
convert_vcard(contact);
|
||||
}
|
||||
free(line);
|
||||
l++;
|
||||
c = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && n == FBUF_SIZE) {
|
||||
strncat_d(&part_line, buf + c, n - c);
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
}
|
||||
} while (!feof(file));
|
||||
|
||||
free_contact(&contact);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
safe_malloc(const size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc(size);
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "Fatal: can't allocate %lu bytes.\n", size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
strcut_d(char **ds1, char **ds2, const char *src, const char s)
|
||||
{
|
||||
char *part;
|
||||
size_t ds1len, ds2len;
|
||||
|
||||
part = strchr(src, s);
|
||||
if (part == NULL) {
|
||||
*ds1 = safe_malloc(sizeof(char) * (strlen(src) + 1));
|
||||
strcpy(*ds1, src);
|
||||
|
||||
*ds2 = safe_malloc(sizeof(char) * 2);
|
||||
strcpy(*ds2, "");
|
||||
} else {
|
||||
ds2len = strlen(part) - 1;
|
||||
*ds2 = safe_malloc(sizeof(char) * (ds2len + 1));
|
||||
strcpy(*ds2, part + 1);
|
||||
|
||||
ds1len = strlen(src) - (ds2len + 1);
|
||||
*ds1 = safe_malloc(sizeof(char) * (ds1len + 1));
|
||||
strncpy(*ds1, src, ds1len);
|
||||
(*ds1)[ds1len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
strexp_d(char ***dst, const char *src, const char s)
|
||||
{
|
||||
size_t len, i;
|
||||
char **tmp_dst;
|
||||
char *tmp_str;
|
||||
|
||||
len = 0;
|
||||
i = 0;
|
||||
|
||||
if (*dst == NULL) {
|
||||
len = 3;
|
||||
*dst = safe_malloc(sizeof(char *) * len);
|
||||
} else {
|
||||
while(**dst != NULL) {
|
||||
len++;
|
||||
(*dst)++;
|
||||
}
|
||||
*dst -= len;
|
||||
i = len;
|
||||
len += 3;
|
||||
tmp_dst = safe_malloc(sizeof(char *) * len);
|
||||
memcpy(tmp_dst, *dst, sizeof(char *) * (len - 3));
|
||||
free(*dst);
|
||||
*dst = tmp_dst;
|
||||
|
||||
}
|
||||
for (i = i; i < len; i++) {
|
||||
(*dst)[i] = NULL;
|
||||
}
|
||||
|
||||
strcut_d(&(*dst)[len - 3], &(*dst)[len - 2], src, s);
|
||||
|
||||
if (strchr((*dst)[len - 2], s) != NULL) {
|
||||
tmp_str = safe_malloc(sizeof(char) * strlen((*dst)[len - 2]));
|
||||
strcpy(tmp_str, (*dst)[len - 2]);
|
||||
free((*dst)[len - 2]);
|
||||
(*dst)[len - 2] = NULL;
|
||||
strexp_d(&(*dst), tmp_str, s);
|
||||
free(tmp_str);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
strncat_d(char **dst, const char *src, const size_t sz)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (*dst == NULL)
|
||||
*dst = "";
|
||||
|
||||
tmp = safe_malloc(sizeof(char) * (sz + strlen(*dst) + 1));
|
||||
|
||||
strcpy(tmp, *dst);
|
||||
if (strcmp(*dst, "") != 0)
|
||||
free(*dst);
|
||||
strncat(tmp, src, sz);
|
||||
*dst = tmp;
|
||||
}
|
||||
|
||||
void
|
||||
strrmchar_d(char **str, const char r)
|
||||
{
|
||||
char *tmp;
|
||||
size_t len, i, c;
|
||||
|
||||
len = strlen(*str);
|
||||
tmp = safe_malloc(sizeof(char) * (len + 1));
|
||||
c = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((*str)[i] == r)
|
||||
continue;
|
||||
tmp[c] = (*str)[i];
|
||||
c++;
|
||||
}
|
||||
tmp[c] = '\0';
|
||||
|
||||
free(*str);
|
||||
*str = safe_malloc(sizeof(char) * c);
|
||||
strcpy(*str, tmp);
|
||||
free(tmp);
|
||||
}
|
Loading…
Reference in New Issue