docs: def _read(self, fp, fpname):
          '''
          Makes the following changes from the RawConfigParser:
  
          1. Strip leading tabs from non-section-header lines.
          2. Treat 8 spaces at the beginning of a line as a tab.
          3. Treat lines beginning with a tab as options.
          4. Drops support for continuation lines.
          5. Multiple values for a given option are stored as a list.
          6. Keys and values are decoded to the system encoding.
          '''
          cursect = None                        # None, or a dictionary
          optname = None
          lineno = 0
          e = None                              # None, or an exception
          while True:
              line = salt.utils.stringutils.to_unicode(fp.readline())
              if not line:
                  break
              lineno = lineno + 1
              # comment or blank line?
              if line.strip() == '' or line[0] in '#;':
                  continue
              if line.split(None, 1)[0].lower() == 'rem' and line[0] in 'rR':
                  # no leading whitespace
                  continue
              # Replace space indentation with a tab. Allows parser to work
              # properly in cases where someone has edited the git config by hand
              # and indented using spaces instead of tabs.
              if line.startswith(self.SPACEINDENT):
                  line = '\t' + line[len(self.SPACEINDENT):]
              # is it a section header?
              mo = self.SECTCRE.match(line)
              if mo:
                  sectname = mo.group('header')
                  if sectname in self._sections:
                      cursect = self._sections[sectname]
                  elif sectname == self.DEFAULTSECT:
                      cursect = self._defaults
                  else:
                      cursect = self._dict()
                      self._sections[sectname] = cursect
                  # So sections can't start with a continuation line
                  optname = None
              # no section header in the file?
              elif cursect is None:
                  raise MissingSectionHeaderError(  # pylint: disable=undefined-variable
                      salt.utils.stringutils.to_str(fpname),
                      lineno,
                      salt.utils.stringutils.to_str(line))
              # an option line?
              else:
                  mo = self._optcre.match(line.lstrip())
                  if mo:
                      optname, vi, optval = mo.group('option', 'vi', 'value')
                      optname = self.optionxform(optname.rstrip())
                      if optval is None:
                          optval = ''
                      if optval:
                          if vi in ('=', ':') and ';' in optval:
                              # ';' is a comment delimiter only if it follows
                              # a spacing character
                              pos = optval.find(';')
                              if pos != -1 and optval[pos-1].isspace():
                                  optval = optval[:pos]
                          optval = optval.strip()
                          # Empty strings should be considered as blank strings
                          if optval in ('""', "''"):
                              optval = ''
                      self._add_option(cursect, optname, optval)
                  else:
                      # a non-fatal parsing error occurred.  set up the
                      # exception but keep going. the exception will be
                      # raised at the end of the file and will contain a
                      # list of all bogus lines
                      if not e:
                          e = ParsingError(fpname)  # pylint: disable=undefined-variable
                      e.append(lineno, repr(line))
          # if any parsing errors occurred, raise an exception
          if e:
              raise e