#include #include /* * Convert CSV to TSV. * Based on https://en.wikipedia.org/wiki/Comma-separated_values * * Copyright (c) 2023 R.J. van der Putten, Leiden, Holland, * rob at sput dot nl. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ int main(void) { int i, qf; char *fp, line[4096]; i = 0; qf = 0; /* Field in quotes when not zero */ fp = NULL; /* Start of field */ memset(line, 0, 4096); while (fgets(line, 4088, stdin)) { if (qf == 0 && line[0] == '\"') { /* 1st field is quoted */ qf = 1; if (line[1] == 10 || line[1] == 13) { /* Blank line */ i = 0; fp = line; continue; /* Read next line */ } i = 1; fp = line + 1; } else { /* 1st field isn't quoted or quoted field with line wrap */ i = 0; fp = line; } while (line[i] != 0) { /* Delimiters */ if (strncmp(line + i, "\"\"\",", 4) == 0) { /* Double quote at end of quoted field */ i++; line[i] = 0; printf("%s\t", fp); i++; fp = NULL; qf = 0; } else if (strncmp(line + i, "\"\",", 3) == 0) { /* Double quote comma */ i++; line[i] = 0; printf("%s", fp); fp = line + i + 1; } else if (strncmp(line + i, "\",", 2) == 0) { /* End of quoted field */ line[i] = 0; printf("%s\t", fp); fp = NULL; /* Disable printf() */ qf = 0; } else if (qf == 0 && strncmp(line + i, ",\"", 2) == 0) { /* Start of quoted field */ line[i] = 0; if (fp != NULL) { /* Printf not disabled */ printf("%s\t", fp); } i++; fp = line + i + 1; /* Next field */ qf = 1; if (fp[0] == 10 || fp[0] == 13) { /* Blank line */ i = 0; fp = line; break; /* Read next line */ } } else if (qf == 0 && line[i] == ',') { /* End and start of field */ line[i] = 0; if (fp != NULL) { /* Printf not disabled */ printf("%s\t", fp); } fp = line + i + 1; /* Next field */ /* Double quotes */ } else if (strncmp(line + i, "\"\"", 2) == 0 && \ line[i + 2] != 10 && line[i + 2] != 13) { /* Double quote is not at end of line */ line[i] = 0; if (fp != NULL) { /* Printf not disabled */ printf("%s", fp); } fp = line + i + 1; /* White space */ } else if (line[i] == 10 || line[i] == 13) { /* End of line */ if (qf == 0) { /* Field isn't quoted */ line[i] = 10; line[i + 1] = 0; } else { if (i != 0 && line[i - 1] == '\"') { /* Remove quote at end of line */ line[i - 1] = 10; line[i] = 0; qf = 0; } else { /* Wrapped record */ line[i] = ' '; line[i + 1] = 0; } } printf("%s", fp); break; } else if (line[i] == 9) { /* Tab */ line[i] = ' '; } i++; } /* End of while line[i] != 0 */ } /* End of while fgets line */ return(0); }