// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
*   Copyright (C) 2003, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  ucdmerge.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2003feb20
*   created by: Markus W. Scherer
*
*   Simple tool for Unicode Character Database files with semicolon-delimited fields.
*   Merges adjacent, identical per-code point data lines into one line with range syntax.
*
*   To compile, just call a C compiler/linker with this source file.
*   On Windows: cl ucdmerge.c
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static const char *
skipWhitespace(const char *s) {
    while(*s==' ' || *s=='\t') {
        ++s;
    }
    return s;
}

/* return the first character position after the end of the data */
static char *
endOfData(const char *l) {
    char *end;
    char c;

    end=strchr(l, '#');
    if(end!=NULL) {
        /* ignore whitespace before the comment */
        while(l!=end && ((c=*(end-1))==' ' || c=='\t')) {
            --end;
        }
    } else {
        end=strchr(l, 0);
    }
    return end;
}

static int
sameData(const char *l1, const char *l2) {
    char *end1, *end2;
    int length;

    /* find the first semicolon in each line - there must be one */
    l1=strchr(l1, ';')+1;
    l2=strchr(l2, ';')+1;

    /* find the end of data: end of string or start of comment */
    end1=endOfData(l1);
    end2=endOfData(l2);

    /* compare the line data portions */
    length=end1-l1;
    return length==(end2-l2) && 0==memcmp(l1, l2, length);
}

extern int
main(int argc, const char *argv[]) {
    static char line[2000], firstLine[2000], lastLine[2000];
    char *end;
    long first, last, c;
    int finished;

    first=last=-1;
    finished=0;

    for(;;) {
        if(gets(line)!=NULL) {
            /* parse the initial code point, if any */
            c=strtol(line, &end, 16);
            if(end!=line && *skipWhitespace(end)==';') {
                /* single code point followed by semicolon and data, keep c */
            } else {
                c=-1;
            }
        } else {
            line[0]=0;
            c=-1;
            finished=1;
        }

        if(last>=0 && (c!=(last+1) || !sameData(firstLine, line))) {
            /* output the current range */
            if(first==last) {
                /* there was no range, just output the one line we found */
                puts(firstLine);
            } else {
                /* there was a real range, merge their lines */
                end=strchr(lastLine, '#');
                if(end==NULL) {
                    /* no comment in second line */
                    printf("%04lX..%04lX%s\n",
                            first, last,            /* code point range */
                            strchr(firstLine, ';'));/* first line starting from the first ; */
                } else if(strchr(firstLine, '#')==NULL) {
                    /* no comment in first line */
                    printf("%04lX..%04lX%s%s\n",
                            first, last,            /* code point range */
                            strchr(firstLine, ';'), /* first line starting from the first ; */
                            end);                   /* comment from second line */
                } else {
                    /* merge comments from both lines */
                    printf("%04lX..%04lX%s..%s\n",
                            first, last,            /* code point range */
                            strchr(firstLine, ';'), /* first line starting from the first ; */
                            skipWhitespace(end+1)); /* comment from second line, after # and spaces */
                }
            }
            first=last=-1;
        }

        if(c<0) {
            if(finished) {
                break;
            }

            /* no data on this line, output as is */
            puts(line);
        } else {
            /* data on this line, store for possible range compaction */
            if(last<0) {
                /* set as the first line in a possible range */
                first=last=c;
                strcpy(firstLine, line);
                lastLine[0]=0;
            } else /* must be c==(last+1) && sameData() because of previous conditions */ {
                /* continue with the current range */
                last=c;
                strcpy(lastLine, line);
            }
        }
    }

    return 0;
}
