[BACK]Return to mdoc.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/mdoc.c between version 1.61 and 1.68

version 1.61, 2009/03/11 00:39:58 version 1.68, 2009/03/20 15:14:01
Line 1 
Line 1 
 /* $Id$ */  /* $Id$ */
 /*  /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>   * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the   * purpose with or without fee is hereby granted, provided that the
Line 29 
Line 29 
 /*  /*
  * Main caller in the libmdoc library.  This begins the parsing routine,   * Main caller in the libmdoc library.  This begins the parsing routine,
  * handles allocation of data, and so forth.  Most of the "work" is done   * handles allocation of data, and so forth.  Most of the "work" is done
  * in macro.c and validate.c.   * in macro.c, validate.c and action.c.
  */   */
   
 static  struct mdoc_node *mdoc_node_alloc(const struct mdoc *);  static  struct mdoc_node *mdoc_node_alloc(const struct mdoc *);
Line 73  const char *const __mdoc_macronames[MDOC_MAX] = {   
Line 73  const char *const __mdoc_macronames[MDOC_MAX] = {   
         "Bk",           "Ek",           "Bt",           "Hf",          "Bk",           "Ek",           "Bt",           "Hf",
         "Fr",           "Ud",           "Lb",           "Ap",          "Fr",           "Ud",           "Lb",           "Ap",
         "Lp",           "Lk",           "Mt",           "Brq",          "Lp",           "Lk",           "Mt",           "Brq",
         "Bro",          "Brc"          /* LINTED */
           "Bro",          "Brc",          "\%C",          "Es",
           "En",           "Dx"
         };          };
   
 const   char *const __mdoc_argnames[MDOC_ARG_MAX] = {  const   char *const __mdoc_argnames[MDOC_ARG_MAX] = {
Line 85  const char *const __mdoc_argnames[MDOC_ARG_MAX] = {   
Line 87  const char *const __mdoc_argnames[MDOC_ARG_MAX] = {   
         "ohang",                "inset",                "column",          "ohang",                "inset",                "column",
         "width",                "compact",              "std",          "width",                "compact",              "std",
         "filled",               "words",                "emphasis",          "filled",               "words",                "emphasis",
         "symbolic"          "symbolic",             "nested"
         };          };
   
 const   char * const *mdoc_macronames = __mdoc_macronames;  const   char * const *mdoc_macronames = __mdoc_macronames;
 const   char * const *mdoc_argnames = __mdoc_argnames;  const   char * const *mdoc_argnames = __mdoc_argnames;
   
   
   /*
    * Get the first (root) node of the parse tree.
    */
 const struct mdoc_node *  const struct mdoc_node *
 mdoc_node(const struct mdoc *mdoc)  mdoc_node(const struct mdoc *mdoc)
 {  {
   
           if (MDOC_HALT & mdoc->flags)
                   return(NULL);
           if (mdoc->first)
                   assert(MDOC_ROOT == mdoc->first->type);
         return(mdoc->first);          return(mdoc->first);
 }  }
   
Line 104  const struct mdoc_meta *
Line 113  const struct mdoc_meta *
 mdoc_meta(const struct mdoc *mdoc)  mdoc_meta(const struct mdoc *mdoc)
 {  {
   
           if (MDOC_HALT & mdoc->flags)
                   return(NULL);
         return(&mdoc->meta);          return(&mdoc->meta);
 }  }
   
   
   /*
    * Free up all resources contributed by a parse:  the node tree, meta-data and
    * so on.  Then reallocate the root node for another parse.
    */
 void  void
   mdoc_reset(struct mdoc *mdoc)
   {
   
           if (mdoc->first)
                   mdoc_node_freelist(mdoc->first);
           if (mdoc->meta.title)
                   free(mdoc->meta.title);
           if (mdoc->meta.os)
                   free(mdoc->meta.os);
           if (mdoc->meta.name)
                   free(mdoc->meta.name);
           if (mdoc->meta.arch)
                   free(mdoc->meta.arch);
           if (mdoc->meta.vol)
                   free(mdoc->meta.vol);
   
           bzero(&mdoc->meta, sizeof(struct mdoc_meta));
           mdoc->flags = 0;
           mdoc->lastnamed = mdoc->lastsec = 0;
   
           mdoc->first = mdoc->last =
                   xcalloc(1, sizeof(struct mdoc_node));
           mdoc->last->type = MDOC_ROOT;
           mdoc->next = MDOC_NEXT_CHILD;
   }
   
   
   /*
    * Completely free up all resources.
    */
   void
 mdoc_free(struct mdoc *mdoc)  mdoc_free(struct mdoc *mdoc)
 {  {
   
         if (mdoc->first)          if (mdoc->first)
                 mdoc_node_freelist(mdoc->first);                  mdoc_node_freelist(mdoc->first);
         if (mdoc->htab)  
                 mdoc_tokhash_free(mdoc->htab);  
         if (mdoc->meta.title)          if (mdoc->meta.title)
                 free(mdoc->meta.title);                  free(mdoc->meta.title);
         if (mdoc->meta.os)          if (mdoc->meta.os)
Line 127  mdoc_free(struct mdoc *mdoc)
Line 171  mdoc_free(struct mdoc *mdoc)
         if (mdoc->meta.vol)          if (mdoc->meta.vol)
                 free(mdoc->meta.vol);                  free(mdoc->meta.vol);
   
           if (mdoc->htab)
                   mdoc_tokhash_free(mdoc->htab);
   
         free(mdoc);          free(mdoc);
 }  }
   
Line 142  mdoc_alloc(void *data, int pflags, const struct mdoc_c
Line 189  mdoc_alloc(void *data, int pflags, const struct mdoc_c
         if (cb)          if (cb)
                 (void)memcpy(&p->cb, cb, sizeof(struct mdoc_cb));                  (void)memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
   
         p->last = xcalloc(1, sizeof(struct mdoc_node));          p->last = p->first =
                   xcalloc(1, sizeof(struct mdoc_node));
         p->last->type = MDOC_ROOT;          p->last->type = MDOC_ROOT;
         p->first = p->last;  
         p->pflags = pflags;          p->pflags = pflags;
         p->next = MDOC_NEXT_CHILD;          p->next = MDOC_NEXT_CHILD;
         p->htab = mdoc_tokhash_alloc();          p->htab = mdoc_tokhash_alloc();
   
         return(p);          return(p);
 }  }
   
   
   /*
    * Climb back up the parse tree, validating open scopes.  Mostly calls
    * through to macro_end in macro.c.
    */
 int  int
 mdoc_endparse(struct mdoc *mdoc)  mdoc_endparse(struct mdoc *mdoc)
 {  {
Line 257  mdoc_macro(struct mdoc *m, int tok, 
Line 307  mdoc_macro(struct mdoc *m, int tok, 
                                 "disallowed in prologue"));                                  "disallowed in prologue"));
   
         if (1 != pp && ! (MDOC_CALLABLE & mdoc_macros[tok].flags))          if (1 != pp && ! (MDOC_CALLABLE & mdoc_macros[tok].flags))
                 return(mdoc_perr(m, ln, pp, "not callable"));                  return(mdoc_perr(m, ln, pp, "%s not callable",
                                           mdoc_macronames[tok]));
   
         return((*mdoc_macros[tok].fp)(m, tok, ln, pp, pos, buf));          return((*mdoc_macros[tok].fp)(m, tok, ln, pp, pos, buf));
 }  }
Line 288  mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *
Line 339  mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *
   
         if ( ! mdoc_valid_pre(mdoc, p))          if ( ! mdoc_valid_pre(mdoc, p))
                 return(0);                  return(0);
           if ( ! mdoc_action_pre(mdoc, p))
                   return(0);
   
         switch (p->type) {          switch (p->type) {
         case (MDOC_HEAD):          case (MDOC_HEAD):
Line 482  mdoc_node_freelist(struct mdoc_node *p)
Line 535  mdoc_node_freelist(struct mdoc_node *p)
  * control character.   * control character.
  */   */
 static int  static int
 parsetext(struct mdoc *mdoc, int line, char *buf)  parsetext(struct mdoc *m, int line, char *buf)
 {  {
   
         if (SEC_PROLOGUE == mdoc->lastnamed)          if (SEC_PROLOGUE == m->lastnamed)
                 return(mdoc_perr(mdoc, line, 0,                  return(mdoc_perr(m, line, 0,
                         "text disallowed in prologue"));                          "text disallowed in prologue"));
   
         if ( ! mdoc_word_alloc(mdoc, line, 0, buf))          if (0 == buf[0] && ! (MDOC_LITERAL & m->flags))
                   return(mdoc_perr(m, line, 0,
                           "blank lines only in literal context"));
   
           if ( ! mdoc_word_alloc(m, line, 0, buf))
                 return(0);                  return(0);
   
         mdoc->next = MDOC_NEXT_SIBLING;          m->next = MDOC_NEXT_SIBLING;
         return(1);          return(1);
 }  }
   
Line 520  parsemacro(struct mdoc *m, int ln, char *buf)
Line 577  parsemacro(struct mdoc *m, int ln, char *buf)
         int               i, c;          int               i, c;
         char              mac[5];          char              mac[5];
   
         /* Comments are quickly ignored. */          /* Comments and empties are quickly ignored. */
   
           if (0 == buf[1])
                   return(1);
   
           if (' ' == buf[1]) {
                   i = 2;
                   while (buf[i] && ' ' == buf[i])
                           i++;
                   if (0 == buf[i])
                           return(1);
                   return(mdoc_perr(m, ln, 1, "invalid syntax"));
           }
   
         if (buf[1] && '\\' == buf[1])          if (buf[1] && '\\' == buf[1])
                 if (buf[2] && '\"' == buf[2])                  if (buf[2] && '\"' == buf[2])
                         return(1);                          return(1);
Line 531  parsemacro(struct mdoc *m, int ln, char *buf)
Line 600  parsemacro(struct mdoc *m, int ln, char *buf)
         for (i = 1; i < 5; i++) {          for (i = 1; i < 5; i++) {
                 if (0 == (mac[i - 1] = buf[i]))                  if (0 == (mac[i - 1] = buf[i]))
                         break;                          break;
                 else if (isspace((unsigned char)buf[i]))                  else if (' ' == buf[i])
                         break;                          break;
         }          }
   
         /* FIXME: be able to skip unknown macro lines! */  
   
         mac[i - 1] = 0;          mac[i - 1] = 0;
   
         if (i == 5 || i <= 2) {          if (i == 5 || i <= 2) {
Line 553  parsemacro(struct mdoc *m, int ln, char *buf)
Line 620  parsemacro(struct mdoc *m, int ln, char *buf)
   
         /* The macro is sane.  Jump to the next word. */          /* The macro is sane.  Jump to the next word. */
   
         while (buf[i] && isspace((unsigned char)buf[i]))          while (buf[i] && ' ' == buf[i])
                 i++;                  i++;
   
         /* Begin recursive parse sequence. */          /* Begin recursive parse sequence. */
   
         if ( ! mdoc_macro(m, c, ln, 1, &i, buf))          if ( ! mdoc_macro(m, c, ln, 1, &i, buf))
                 goto err;                  goto err;
   
           /*
            * If we're in literal mode, then add a newline to the end of
            * macro lines.  Our frontends will interpret this correctly
            * (it's documented in mdoc.3).
            */
   
         return(1);          return(1);
   

Legend:
Removed from v.1.61  
changed lines
  Added in v.1.68

CVSweb