fork(2) download
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <assert.h>
  4.  
  5. char* expand_cell_references(const char* f, const char* const l, char* o); /*the magic engine*/
  6. const char* get_cell_value(const char* coordinate_b, const char* coordinate_e);
  7.  
  8. const char* cells[][4] = {
  9. /* A B C D */
  10. { "the" , "lazy" , "cow" , "jumped" }, /* 1 */
  11. { "over" , "the" , "quick", "brown" }, /* 2 */
  12. { "paper", "packages", "tied" , "up" }, /* 3 */
  13. { "with" , "silver" , "white", "winters" }, /* 4 */
  14. { "that" , "melt" , "fox" , "springs" }, /* 5 */
  15. };
  16.  
  17. const char* get_cell_value(const char* coordinate_b, const char* coordinate_e)
  18. {
  19. #ifdef DEBUG
  20. static const int maxrows = (sizeof(cells)/sizeof(*cells));
  21. static const int maxcols = (sizeof(cells[0])/sizeof(*cells[0]));
  22. #endif
  23. size_t col = 0, row = 0;
  24. const char* it;
  25. for (it=coordinate_b; it != coordinate_e; ++it)
  26. {
  27. if (*it >= 'A' && *it <= 'Z')
  28. col = 26*col + (*it - 'A');
  29. if (*it >= '0' && *it <= '9')
  30. row = 10*row + (*it - '0'); /* or use atoi and friends */
  31. }
  32. row--; /* 1-based row nums in Excel */
  33.  
  34. #ifdef DEBUG
  35. assert(col>=0 && col < maxcols);
  36. assert(row>=0 && row < maxrows);
  37. #endif
  38.  
  39. return cells[row][col]; /* 1-based indexes in Excel */
  40. }
  41.  
  42. int main()
  43. {
  44. const char in[] = "The C2{D2 * (C5+D1) - Foo(A2;B2;B1) dog}!";
  45.  
  46. char out[1024] = {0};
  47. expand_cell_references(in, in+strlen(in), out);
  48. puts(out); /* "The quick brown fox jumped over the lazy dog!" */
  49.  
  50. return 0;
  51. }
  52.  
  53. char* expand_cell_references(const char* f, const char* const l, char* o)
  54. {
  55. enum parser_state {
  56. other,
  57. in_coord_col,
  58. in_coord_row
  59. } state = other;
  60.  
  61. /*temporary storage for coordinates being parsed:*/
  62. char accum[16] = {0};
  63. char* accit = accum;
  64. while (f!=l)
  65. {
  66. switch(state) /*dummy, the transitions flow in fallthrough order for now*/
  67. {
  68. case other:
  69. *(accit = accum) = 0; /*reset the accumulator*/
  70. while (f!=l && !(*f>='A' && *f<='Z'))
  71. *o++ = *f++;
  72. /*fallthrough*/
  73. case in_coord_col:
  74. while (f!=l && *f>='A' && *f<='Z')
  75. *accit++ = *f++;
  76. /*fallthrough*/
  77. case in_coord_row:
  78. {
  79. const char* expanded = accum;
  80. if (f!=l && *f>='0' && *f<='9')
  81. {
  82. while (f!=l && *f>='0' && *f<='9')
  83. *accit++ = *f++;
  84. expanded = get_cell_value(accum, accit);
  85. }
  86. else
  87. {
  88. *accit = 0;
  89. }
  90. while (*expanded)
  91. *o++ = *expanded++;
  92. continue; /*state = other;*/
  93. }
  94. }
  95. }
  96. return o;
  97. }
  98.  
Success #stdin #stdout 0s 1832KB
stdin
Standard input is empty
stdout
The quick{brown * (fox+jumped) - Foo(over;the;lazy) dog}!