c – Decode alphabet encoded message

Inspired by another Q I finally made a version that groups permutable regions into parentheses. Non-ambigous sequences are outside of parens.

Alphabet Code: A=1, B=2, ..., Z=26

Output (4 examples):

1234567891011121314151617181920212223242526 (Code)
(ABC)DEFGHIJ(AAABAC)(AD)(AE)(AF)(AG)(AH)(AI)T(BABBBC)(BD)(BE)(BF) (Decoded: single, grouped) 

314159265358979323846 (Code)
C(AD)(AE)I(BF)ECEHIGIC(BC)HDF (Decoded: single, grouped) 

11011 (Code)
AJ(AA) (Decoded: single, grouped) 

22202 (Code)
(BB)TB (Decoded: single, grouped) 

18446744073709551616 (Code)
(AH)DDFGD******* Error: zero 30-90

The code is quite long and complicated. The parens seem to be correct now.

Is there a simpler way to achieve this?

The basic idea still seems straight forward, but I end up with two screens full of ifs. (But it is done in one pass)

Or is it silly to decode / reconstruct the message when it is scrambled like that?

/* 
Decode Fawlty 0x10-shift code (leading zeros lost)
A=1, B=2, ..., Z=26
"111" can thus be "AAA", "AK" or "KA"
Orig. Q. was: 
How to count the possible combinations in a message?
This puts freely permutable regions into parentheses,
giving only the single-digit interpretation.
For above "111", output would be "(AAA)"
*/

#include <stdio.h>

void parse_msg(char *msg) {

    char c, cprev, cnext;
    int i;
    /* Start in a state like after a high digit 3..9 */
    cprev = '9';
    for (i = 0; msg(i) != ''; i++) {

        c     = msg(i);
        cnext = msg(i+1);

        /* Make sure 'cnext' is all the look-ahead that is needed */
        /* pull a far ahead "10" or "20" into cnext as '' */
        if (cnext != '')
            if (msg(i+2) == '0') 
                cnext = '';

        /* "10" and "20" are special cases, get rid of them */
        if (cnext == '0') {
            if (cprev <= '2')
                printf(")");
            if (c == '1')
                printf("J");
            if (c == '2')
                printf("T");
            if (c >= '3') {
                printf("******* Error: zero 30-90n");
                return;
            }
            cprev = '9'; // reset to outside-of-group 
            i++;         // extra skip in msg
            continue;
        }

        /* ONE: Always open a "(" group, unless cnext is the (fake or real) null byte */
        if (c == '1') {
            if (cprev >= '3')
                if (cnext == '')
                    cprev = '9';
                else {
                    printf("(");
                    cprev = c;
                }
            printf("A");
            continue;
        }

        /* TWO: Maybe open before, or close after, plus set cprev */
        if (c == '2') {
            /* 32*: is closed, can open */
            if (cprev >= '3') {
                /* 32: dont open, but mark as closed */
                if (cnext == '') {
                    printf("B");
                    cprev = '9';
                    continue;
                }
                /* 321-926: open before */
                if (cnext <= '6')
                    printf("(");
            }

            printf("B");

            /* "127", "229": is open, must close */
            if (cprev <= '2' && cnext >= '7' ) {
                printf(")");
                cprev = '9';
                continue;
            }

            cprev = c;
            continue;
        }
            
        /* c == '3' or higher are left */
        /* THREE+: No opening */
        printf("%c", c + 0x10 );

        /* if open, then close group ")" after printing */
        if (cprev == '1' || cprev == '2' && c <= '6' )
            printf(")");

        /* 3..9 marks state as "closed" */
        cprev = c;
    }

    /* End of 'msg' reached: close if opened */
    if (cprev <= '2')
        printf(")");
    printf(" (Decoded: single, grouped) n");

    return;
}

int main(void) {

    char *msg = "1234567891011121314151617181920212223242526";
    printf("%s (Code)n", msg);
    parse_msg(msg);

    msg = "314159265358979323846";
    printf("n%s (Code)n", msg);
    parse_msg(msg);

    msg = "11011";
    printf("n%s (Code)n", msg);
    parse_msg(msg);

    msg = "22202";
    printf("n%s (Code)n", msg);
    parse_msg(msg);

    msg = "18446744073709551616";
    printf("n%s (Code)n", msg);
    parse_msg(msg);

    return 0;