#include <string.h>
#include <stdio.h>
#include <assert.h>
char* expand_cell_references(const char* f, const char* const l, char* o); /*the magic engine*/
const char* get_cell_value(const char* coordinate_b, const char* coordinate_e);
const char* cells[][4] = {
/* A B C D */
{ "the" , "lazy" , "cow" , "jumped" }, /* 1 */
{ "over" , "the" , "quick", "brown" }, /* 2 */
{ "paper", "packages", "tied" , "up" }, /* 3 */
{ "with" , "silver" , "white", "winters" }, /* 4 */
{ "that" , "melt" , "fox" , "springs" }, /* 5 */
};
const char* get_cell_value(const char* coordinate_b, const char* coordinate_e)
{
#ifdef DEBUG
static const int maxrows = (sizeof(cells)/sizeof(*cells));
static const int maxcols = (sizeof(cells[0])/sizeof(*cells[0]));
#endif
size_t col = 0, row = 0;
const char* it;
for (it=coordinate_b; it != coordinate_e; ++it)
{
if (*it >= 'A' && *it <= 'Z')
col = 26*col + (*it - 'A');
if (*it >= '0' && *it <= '9')
row = 10*row + (*it - '0'); /* or use atoi and friends */
}
row--; /* 1-based row nums in Excel */
#ifdef DEBUG
assert(col
>=0 && col
< maxcols
); assert(row
>=0 && row
< maxrows
); #endif
return cells[row][col]; /* 1-based indexes in Excel */
}
int main()
{
const char in[] = "The C2 D2 C5 D1 A2 B2 B1 dog!";
char out[1024] = {0};
expand_cell_references
(in
, in
+strlen(in
), out
); puts(out
); /* "The quick brown fox jumped over the lazy dog!" */
return 0;
}
char* expand_cell_references(const char* f, const char* const l, char* o)
{
enum parser_state {
other,
in_coord_col,
in_coord_row
} state = other;
/*temporary storage for coordinates being parsed:*/
char accum[16] = {0};
char* accit = accum;
while (f!=l)
{
switch(state) /*dummy, the transitions flow in fallthrough order for now*/
{
case other:
*(accit = accum) = 0; /*reset the accumulator*/
while (f!=l && !(*f>='A' && *f<='Z'))
*o++ = *f++;
/*fallthrough*/
case in_coord_col:
while (f!=l && *f>='A' && *f<='Z')
*accit++ = *f++;
/*fallthrough*/
case in_coord_row:
{
const char* expanded = accum;
if (f!=l && *f>='0' && *f<='9')
{
while (f!=l && *f>='0' && *f<='9')
*accit++ = *f++;
expanded = get_cell_value(accum, accit);
}
else
{
*accit = 0;
}
while (*expanded)
*o++ = *expanded++;
continue; /*state = other;*/
}
}
}
return o;
}
I2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKY2hhciogZXhwYW5kX2NlbGxfcmVmZXJlbmNlcyhjb25zdCBjaGFyKiBmLCBjb25zdCBjaGFyKiBjb25zdCBsLCBjaGFyKiBvKTsgLyp0aGUgbWFnaWMgZW5naW5lKi8KY29uc3QgY2hhciogZ2V0X2NlbGxfdmFsdWUoY29uc3QgY2hhciogY29vcmRpbmF0ZV9iLCBjb25zdCBjaGFyKiBjb29yZGluYXRlX2UpOwoKY29uc3QgY2hhciogY2VsbHNbXVs0XSA9IHsKICAgIC8qIEEgICAgICAgQiAgICAgICAgICAgQyAgICAgICAgRCAgICAgICAgICAgICAgICAgKi8KICAgIHsgInRoZSIgICwgImxhenkiICAgICwgImNvdyIgICwgImp1bXBlZCIgIH0sIC8qIDEgKi8KICAgIHsgIm92ZXIiICwgInRoZSIgICAgICwgInF1aWNrIiwgImJyb3duIiAgIH0sIC8qIDIgKi8KICAgIHsgInBhcGVyIiwgInBhY2thZ2VzIiwgInRpZWQiICwgInVwIiAgICAgIH0sIC8qIDMgKi8KICAgIHsgIndpdGgiICwgInNpbHZlciIgICwgIndoaXRlIiwgIndpbnRlcnMiIH0sIC8qIDQgKi8KICAgIHsgInRoYXQiICwgIm1lbHQiICAgICwgImZveCIgLCAgInNwcmluZ3MiIH0sIC8qIDUgKi8KfTsKCmNvbnN0IGNoYXIqIGdldF9jZWxsX3ZhbHVlKGNvbnN0IGNoYXIqIGNvb3JkaW5hdGVfYiwgY29uc3QgY2hhciogY29vcmRpbmF0ZV9lKQp7CiNpZmRlZiBERUJVRwogICAgc3RhdGljIGNvbnN0IGludCBtYXhyb3dzID0gKHNpemVvZihjZWxscykvc2l6ZW9mKCpjZWxscykpOwogICAgc3RhdGljIGNvbnN0IGludCBtYXhjb2xzID0gKHNpemVvZihjZWxsc1swXSkvc2l6ZW9mKCpjZWxsc1swXSkpOwojZW5kaWYKICAgIHNpemVfdCBjb2wgPSAwLCByb3cgPSAwOwogICAgY29uc3QgY2hhciogaXQ7CiAgICBmb3IgKGl0PWNvb3JkaW5hdGVfYjsgaXQgIT0gY29vcmRpbmF0ZV9lOyArK2l0KQogICAgewogICAgICAgIGlmICgqaXQgPj0gJ0EnICYmICppdCA8PSAnWicpCiAgICAgICAgICAgIGNvbCA9IDI2KmNvbCArICgqaXQgLSAnQScpOwogICAgICAgIGlmICgqaXQgPj0gJzAnICYmICppdCA8PSAnOScpCiAgICAgICAgICAgIHJvdyA9IDEwKnJvdyArICgqaXQgLSAnMCcpOyAvKiBvciB1c2UgYXRvaSBhbmQgZnJpZW5kcyAqLwogICAgfQogICAgcm93LS07IC8qIDEtYmFzZWQgcm93IG51bXMgaW4gRXhjZWwgKi8KCiNpZmRlZiBERUJVRwogICAgYXNzZXJ0KGNvbD49MCAmJiBjb2wgPCBtYXhjb2xzKTsKICAgIGFzc2VydChyb3c+PTAgJiYgcm93IDwgbWF4cm93cyk7CiNlbmRpZgoKICAgIHJldHVybiBjZWxsc1tyb3ddW2NvbF07IC8qIDEtYmFzZWQgaW5kZXhlcyBpbiBFeGNlbCAqLwp9CgppbnQgbWFpbigpCnsKICAgIGNvbnN0IGNoYXIgaW5bXSA9ICJUaGUgQzIgRDIgQzUgRDEgQTIgQjIgQjEgZG9nISI7CgogICAgY2hhciBvdXRbMTAyNF0gPSB7MH07CiAgICBleHBhbmRfY2VsbF9yZWZlcmVuY2VzKGluLCBpbitzdHJsZW4oaW4pLCBvdXQpOwogICAgcHV0cyhvdXQpOyAvKiAiVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2chIiAqLwoKICAgIHJldHVybiAwOwp9CgpjaGFyKiBleHBhbmRfY2VsbF9yZWZlcmVuY2VzKGNvbnN0IGNoYXIqIGYsIGNvbnN0IGNoYXIqIGNvbnN0IGwsIGNoYXIqIG8pCnsKICAgIGVudW0gcGFyc2VyX3N0YXRlIHsKICAgICAgICBvdGhlciwKICAgICAgICBpbl9jb29yZF9jb2wsCiAgICAgICAgaW5fY29vcmRfcm93CiAgICB9IHN0YXRlID0gb3RoZXI7CgogICAgLyp0ZW1wb3Jhcnkgc3RvcmFnZSBmb3IgY29vcmRpbmF0ZXMgYmVpbmcgcGFyc2VkOiovCiAgICBjaGFyIGFjY3VtWzE2XSA9IHswfTsKICAgIGNoYXIqIGFjY2l0ID0gYWNjdW07CiAgICB3aGlsZSAoZiE9bCkKICAgIHsKICAgICAgICBzd2l0Y2goc3RhdGUpIC8qZHVtbXksIHRoZSB0cmFuc2l0aW9ucyBmbG93IGluIGZhbGx0aHJvdWdoIG9yZGVyIGZvciBub3cqLwogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBvdGhlcjoKICAgICAgICAgICAgICAgICooYWNjaXQgPSBhY2N1bSkgPSAwOyAvKnJlc2V0IHRoZSBhY2N1bXVsYXRvciovCiAgICAgICAgICAgICAgICB3aGlsZSAoZiE9bCAmJiAhKCpmPj0nQScgJiYgKmY8PSdaJykpCiAgICAgICAgICAgICAgICAgICAgKm8rKyA9ICpmKys7CiAgICAgICAgICAgICAgICAvKmZhbGx0aHJvdWdoKi8KICAgICAgICAgICAgY2FzZSBpbl9jb29yZF9jb2w6CiAgICAgICAgICAgICAgICB3aGlsZSAoZiE9bCAmJiAqZj49J0EnICYmICpmPD0nWicpCiAgICAgICAgICAgICAgICAgICAgKmFjY2l0KysgPSAqZisrOwogICAgICAgICAgICAgICAgLypmYWxsdGhyb3VnaCovCiAgICAgICAgICAgIGNhc2UgaW5fY29vcmRfcm93OgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGFuZGVkID0gYWNjdW07CiAgICAgICAgICAgICAgICAgICAgaWYgKGYhPWwgJiYgKmY+PScwJyAmJiAqZjw9JzknKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGYhPWwgJiYgKmY+PScwJyAmJiAqZjw9JzknKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKmFjY2l0KysgPSAqZisrOwogICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRlZCA9IGdldF9jZWxsX3ZhbHVlKGFjY3VtLCBhY2NpdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICphY2NpdCA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHdoaWxlICgqZXhwYW5kZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICpvKysgPSAqZXhwYW5kZWQrKzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLypzdGF0ZSA9IG90aGVyOyovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIG87Cn0K