| 5723 | } |
| 5724 | |
| 5725 | static int |
| 5726 | xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields, |
| 5727 | unsigned num_fields, const char *fmt) |
| 5728 | { |
| 5729 | const char *cp, *sp, *ep, *basep; |
| 5730 | unsigned field = 0; |
| 5731 | xo_field_info_t *xfip = fields; |
| 5732 | unsigned seen_fnum = 0; |
| 5733 | |
| 5734 | for (cp = fmt; *cp && field < num_fields; field++, xfip++) { |
| 5735 | xfip->xfi_start = cp; |
| 5736 | |
| 5737 | if (*cp == '\n') { |
| 5738 | xfip->xfi_ftype = XO_ROLE_NEWLINE; |
| 5739 | xfip->xfi_len = 1; |
| 5740 | cp += 1; |
| 5741 | continue; |
| 5742 | } |
| 5743 | |
| 5744 | if (*cp != '{') { |
| 5745 | /* Normal text */ |
| 5746 | for (sp = cp; *sp; sp++) { |
| 5747 | if (*sp == '{' || *sp == '\n') |
| 5748 | break; |
| 5749 | } |
| 5750 | |
| 5751 | xfip->xfi_ftype = XO_ROLE_TEXT; |
| 5752 | xfip->xfi_content = cp; |
| 5753 | xfip->xfi_clen = sp - cp; |
| 5754 | xfip->xfi_next = sp; |
| 5755 | |
| 5756 | cp = sp; |
| 5757 | continue; |
| 5758 | } |
| 5759 | |
| 5760 | if (cp[1] == '{') { /* Start of {{escaped braces}} */ |
| 5761 | xfip->xfi_start = cp + 1; /* Start at second brace */ |
| 5762 | xfip->xfi_ftype = XO_ROLE_EBRACE; |
| 5763 | |
| 5764 | cp += 2; /* Skip over _both_ characters */ |
| 5765 | for (sp = cp; *sp; sp++) { |
| 5766 | if (*sp == '}' && sp[1] == '}') |
| 5767 | break; |
| 5768 | } |
| 5769 | if (*sp == '\0') { |
| 5770 | xo_failure(xop, "missing closing '}}': '%s'", |
| 5771 | xo_printable(fmt)); |
| 5772 | return -1; |
| 5773 | } |
| 5774 | |
| 5775 | xfip->xfi_len = sp - xfip->xfi_start + 1; |
| 5776 | |
| 5777 | /* Move along the string, but don't run off the end */ |
| 5778 | if (*sp == '}' && sp[1] == '}') /* Paranoid; must be true */ |
| 5779 | sp += 2; |
| 5780 | |
| 5781 | cp = sp; |
| 5782 | xfip->xfi_next = cp; |
no test coverage detected