grepfile - greps a specific file

    Args:
        fpath (str):
        regexpr_list (list or str): pattern or list of patterns

    Returns:
        tuple (list, list): list of lines and list of line numbers

    CommandLine:
        python -m utool.util_path --exec-grepfile

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_path import *  # NOQA
        >>> import utool as ut
        >>> fpath = ut.get_modpath(ut.util_path)
        >>> regexpr_list = ['foundthisline', '__future__']
        >>> cache = None
        >>> reflags = 0
        >>> found_lines, found_lxs = ut.grepfile(fpath, regexpr_list)
        >>> result = ut.repr3({'found_lines': found_lines, 'found_lxs': found_lxs})
        >>> print(result)
        >>> assert 7 in found_lxs
        >>> others = ut.take_complement(found_lxs, [found_lxs.index(7)])
        >>> assert others[0] == others[1]

def grepfile(fpath, regexpr_list, reflags=0, cache=None):
    """
    grepfile - greps a specific file

    Args:
        fpath (str):
        regexpr_list (list or str): pattern or list of patterns

    Returns:
        tuple (list, list): list of lines and list of line numbers

    CommandLine:
        python -m utool.util_path --exec-grepfile

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_path import *  # NOQA
        >>> import utool as ut
        >>> fpath = ut.get_modpath(ut.util_path)
        >>> regexpr_list = ['foundthisline', '__future__']
        >>> cache = None
        >>> reflags = 0
        >>> found_lines, found_lxs = ut.grepfile(fpath, regexpr_list)
        >>> result = ut.repr3({'found_lines': found_lines, 'found_lxs': found_lxs})
        >>> print(result)
        >>> assert 7 in found_lxs
        >>> others = ut.take_complement(found_lxs, [found_lxs.index(7)])
        >>> assert others[0] == others[1]
    """
    found_lines = []
    found_lxs = []
    # Ensure a list
    islist = isinstance(regexpr_list, (list, tuple))
    islist2 = isinstance(reflags, (list, tuple))
    regexpr_list_ = regexpr_list if islist else [regexpr_list]
    reflags_list = reflags if islist2 else [reflags] * len(regexpr_list_)
    re_list = [re.compile(pat, flags=_flags)
               for pat, _flags in  zip(regexpr_list_, reflags_list)]
    #print('regexpr_list_ = %r' % (regexpr_list_,))
    #print('re_list = %r' % (re_list,))

    import numpy as np
    # Open file and search lines or use cache
    if cache is None or fpath not in cache:
        #with open(fpath, 'r') as file_:
        #    lines = list(file_.readlines())
        from utool import util_io
        lines = util_io.read_from(fpath, aslines=True, verbose=False)
        #import utool as ut
        #cumsum = ut.cumsum(map(len, lines))
        cumsum = np.cumsum(list(map(len, lines)))
        text = ''.join(lines)
        if cache is not None:
            cache[fpath] = (cumsum, text, lines)
    else:
        (cumsum, text, lines) = cache[fpath]

    # Search each line for each pattern
    old_method = False
    if old_method:
        for lx, line in enumerate(lines):
            #for regexpr_ in regexpr_list_:
            match_objects = [re_.search(line) for re_ in re_list]
            for match in match_objects:
                if match is not None:
                    found_lines.append(line)
                    found_lxs.append(lx)
    else:
        for re_ in re_list:
            # FIXME: multiline mode doesnt work
            for match_object in re_.finditer(text):
                #print('match_object = %r' % (match_object,))
                lxs = np.where(match_object.start() < cumsum)[0][0:1]
                if len(lxs) == 1:
                    lx = lxs[0]
                    if lx > 0:
                        line_start = cumsum[lx - 1]
                    else:
                        line_start = 0
                    line_end = cumsum[lx]
                    line = text[line_start:line_end]
                    found_lines.append(line)
                    found_lxs.append(lx)
                #[match_object.start > x for x in cumsum]
    return found_lines, found_lxs