/* expand a macro; return zero on success */ static int tok_expand(void) { char *args[10] = {NULL}; struct sbuf sbufs[10]; int i, n = 0; tok_preview(tok); if (src_macro(tok)) { int c = src_next(); src_back(c); if (c == '(') { /* macro arguments follow */ src_next(); while (n <= 9) { sbuf_init(&sbufs[n]); if (tok_readarg(&sbufs[n++])) break; } } for (i = 0; i < n; i++) args[i] = sbuf_buf(&sbufs[i]); src_expand(tok, args); for (i = 0; i < n; i++) sbuf_done(&sbufs[i]); return 0; } tok_unpreview(tok); return 1; }
/* read macro definition */ static void tok_macrodef(struct sbuf *def) { int c; int delim; c = src_next(); while (c > 0 && isspace(c)) c = src_next(); delim = c; c = src_next(); while (c > 0 && c != delim) { sbuf_add(def, c); c = src_next(); } }
/* read the next word */ static void tok_preview(char *s) { int c = src_next(); int n = 0; if (c > 0 && def_chopped(c)) { s[n++] = c; s[n] = '\0'; return; } while (c > 0 && !def_chopped(c) && (!tok_line || (!src_top() || c != eqn_end))) { s[n++] = c; c = src_next(); } s[n] = '\0'; src_back(c); }
/* read the next argument of a macro call; return zero if read a ',' */ static int tok_readarg(struct sbuf *sbuf) { int c = src_next(); int pdepth = 0; /* number of nested parenthesis */ int quotes = 0; /* inside double quotes */ while (c > 0 && (pdepth || quotes || (c != ',' && c != ')'))) { sbuf_add(sbuf, c); if (!quotes && c == ')') pdepth++; if (!quotes && c == '(') pdepth--; if (c == '"') quotes = 1 - quotes; if (c == '\\') { sbuf_add(sbuf, c = src_next()); if (c == '*' || c == 'n') sbuf_add(sbuf, c = src_next()); if (c == '(') { sbuf_add(sbuf, c = src_next()); sbuf_add(sbuf, c = src_next()); } else if (c == '[') { while (c > 0 && c != ']') sbuf_add(sbuf, c = src_next()); } } c = src_next(); } return c == ',' ? 0 : 1; }
/// true if equal bool messages_diff ( gpb::Message const &templ, gpb::Message &src, gpb::FieldDescriptor const *fld ) { gpb::Reflection const *treflect( templ.GetReflection( ) ); gpb::Reflection const *sreflect( src.GetReflection( ) ); if( message_has_repeated( fld ) ) { gpb::Message const &tmpl_next( treflect->GetMessage( templ, fld ) ); gpb::Message *src_next( sreflect->MutableMessage( &src, fld ) ); std::string tmpls(tmpl_next.SerializeAsString()); std::string srss(src_next->SerializeAsString()); return tmpls == srss; } if( !fld->is_repeated( ) ) { gpb::Message const &tmpl_next( treflect->GetMessage( templ, fld ) ); gpb::Message *src_next( sreflect->MutableMessage( &src, fld ) ); bool equal = false; if( make_message_diff( tmpl_next, *src_next, *src_next ) ) { sreflect->ClearField( &src, fld ); equal = true; } return equal; } int tsize( templ.GetReflection( )->FieldSize( templ, fld ) ); int ssize( src.GetReflection( )->FieldSize( src, fld ) ); if( tsize != ssize ) return false; for( int i(0); i<tsize; ++i ) { std::string tmess( treflect->GetRepeatedMessage( templ, fld, i ) .SerializeAsString( ) ); std::string smess( sreflect->GetRepeatedMessage( src, fld, i ) .SerializeAsString( ) ); if( tmess.compare(smess) != 0 ) return false; } sreflect->ClearField( &src, fld ); return true; }
/* return zero if troff request .ab is read */ static int tok_req(int a, int b) { int eqln[LNLEN]; int i = 0; int ret = 0; eqln[i++] = src_next(); if (eqln[i - 1] != '.') goto failed; eqln[i++] = src_next(); while (eqln[i - 1] == ' ' && i < sizeof(eqln) - 4) eqln[i++] = src_next(); if (eqln[i - 1] != a) goto failed; eqln[i++] = src_next(); if (eqln[i - 1] != b) goto failed; ret = 1; failed: while (i > 0) src_back(eqln[--i]); return ret; }
/* read the next input character */ static int tok_next(void) { int c; if (!tok_eqen && !tok_line) return 0; c = src_next(); if (tok_eqen && c == '\n' && tok_en()) tok_eqen = 0; if (tok_line && (src_top() && c == eqn_end)) { tok_line = 0; return 0; } return c; }
/* read until .EQ or eqn_beg */ int tok_eqn(void) { struct sbuf ln; int c; tok_cursep = 1; sbuf_init(&ln); while ((c = src_next()) > 0) { if (c == eqn_beg) { printf(".eo\n"); printf(".%s %s \"%s\n", tok_part ? "as" : "ds", EQNS, sbuf_buf(&ln)); sbuf_done(&ln); printf(".ec\n"); tok_part = 1; tok_line = 1; return 0; } sbuf_add(&ln, c); if (c == '\n' && !tok_part) { printf("%s", sbuf_buf(&ln)); tok_lf(sbuf_buf(&ln)); if (tok_eq(sbuf_buf(&ln)) && !tok_en()) { tok_eqen = 1; sbuf_done(&ln); return 0; } } if (c == '\n' && tok_part) { printf(".lf %d\n", src_lineget()); printf("\\*%s%s", escarg(EQNS), sbuf_buf(&ln)); tok_part = 0; } if (c == '\n') sbuf_cut(&ln, 0); } sbuf_done(&ln); return 1; }