Parsing a configuration file in C I've written the following function to parse a configuration file. I did my best to make it simple, but it's still over 30 lines and has too much indentation caused by a series of if statements.

Any suggestions make it easier to read are welcome.

int
parse_config (FILE * conf_file, module_initializer_t init)
{
  char *line; /* Current line */
  char *type; /* Type of current module */
  char *name; /* Name of current module */
  char *envz;
  size_t envz_len;
  size_t lineno = 0;

  line = type = name = envz = NULL;
  while (getline (&amp;line, NULL, conf_file) != EOF) 
    {
      lineno++ ;
      if (!is_comment(line))
        if (line[0] == '[')
          if (update_header(line, &amp;type, &amp;name)) {
            if (type)
              if ((*init)(type, name, envz, envz_len)) {
                fprintf("failed to initialize module %s with name %s", type, name);
                return 1;
              }
            clear_envz(&amp;envz, &amp;envz_len);
            }
          else {
            fprint("syntax error on line %d", lineno);
            return 1;
          }
      else
        argz_add(&amp;envz, &amp;envz_len, line);
    }
  if ((*init)(type, name, envz, envz_len)) {
    fprintf("failed to initialize module %s with name %s", type, name);
    return 1;
  }
}


It parses a configuration file with the following syntax: 

   #comment and empty lines ignored
   [module-type]{module-name}
   var1=val1
   #comment
   var2=val2
   [another-type]{another-name}
   var3=val3
I would do some re-arranging:
Use the quick exit pattern.

This is basically if it fails the useful criteria exit (or in this case start the next loop). Basically you test for conditions that don't satisfy your working conditions. If the data does not match then you move on.

int
parse_config (FILE * conf_file, module_initializer_t init)
{
  char *line; /* Current line */
  char *type; /* Type of current module */
  char *name; /* Name of current module */
  char *envz;
  size_t envz_len;
  size_t lineno = 0;

  line = type = name = envz = NULL;
  while (getline (&amp;line, NULL, conf_file) != EOF) 
  {
      lineno++ ;
      if (is_comment(line))
      {    continue;        // Ignore comments;
      }

      if (line[0] != '[')
      {
          argz_add(&amp;envz, &amp;envz_len, line);
          continue;         // Processes arguments and continue
      }

      if (!update_header(line, &amp;type, &amp;name))
      {
          fprint("syntax error on line %d", lineno);
          return 1;         // Not an argument and not a header
                            // must be an error.
      }

      // Processes a header
      if (type)
      {
          if ((*init)(type, name, envz, envz_len))
          {
            fprintf("failed to initialize module %s with name %s", type, name);
            return 1;
          }
          clear_envz(&amp;envz, &amp;envz_len);
      }     
  }

  if ((*init)(type, name, envz, envz_len)) {
    fprintf("failed to initialize module %s with name %s", type, name);
    return 1;
  }

  // You should also return a value here.
  return 0;
}