def exec_(interp, cmd, r_output=None, r_return_var=None): space = interp.space if not cmd: raise ExitFunctionWithError('Cannot execute a blank command') if r_output is not None: if not space.is_array(r_output.deref_temp()): r_output.store(space.new_array_from_list([])) w_output = r_output.deref_unique() else: w_output = None try: pfile = create_popen_file(cmd, 'r') except OSError: raise ExitFunctionWithError('Unable to fork [%s]' % cmd, w_Null) last_line = '' while True: line = pfile.readline() if not line: break last_line = line.rstrip() if w_output: w_output.appenditem_inplace(space, space.newstr(last_line)) exitcode = pfile.close() if r_return_var is not None: r_return_var.store(space.wrap(exitcode)) return space.newstr(last_line)
def getfullinfo_charp(re, extra, flag): p_result = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw') rc = _pcre.pcre_fullinfo(re, extra, flag, p_result) result = p_result[0] lltype.free(p_result, flavor='raw') if rc < 0: raise ExitFunctionWithError("Internal pcre_fullinfo() error %d" % rc) return result
def getfullinfo_int(re, extra, flag): p_result = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') rc = _pcre.pcre_fullinfo(re, extra, flag, p_result) result = p_result[0] lltype.free(p_result, flavor='raw') if rc < 0: raise ExitFunctionWithError("Internal pcre_fullinfo() error %d" % rc) return rffi.cast(lltype.Signed, result)
def passthru(interp, cmd, r_return_var=None): space = interp.space if not cmd: raise ExitFunctionWithError('Cannot execute a blank command') try: pfile = create_popen_file(cmd, 'r') except OSError: raise ExitFunctionWithError('Unable to fork [%s]' % cmd, w_Null) last_line = '' while True: line = pfile.read() if not line: break interp.writestr(line, buffer=False) exitcode = pfile.close() if r_return_var is not None: r_return_var.store(space.wrap(exitcode)) return space.newstr(last_line)
def preg_match(interp, pattern, subject, w_matches=None, flags=0, offset=0): pce = get_compiled_regex_cache(interp, pattern) offset_capture = (flags & PREG_OFFSET_CAPTURE) != 0 if flags & 0xff: raise ExitFunctionWithError("Invalid flags specified") return match_impl(interp, pce, subject, w_matches, offset, mode=MODE_MATCH, limit=1, flags=PREG_SPLIT_OFFSET_CAPTURE if offset_capture else 0)
def make_subpats_table(capturecount, re, extra): num_subpats = capturecount + 1 subpat_names = [None] * num_subpats name_cnt = getfullinfo_int(re, extra, _pcre.PCRE_INFO_NAMECOUNT) if name_cnt > 0: name_table = getfullinfo_charp(re, extra, _pcre.PCRE_INFO_NAMETABLE) name_size = getfullinfo_int(re, extra, _pcre.PCRE_INFO_NAMEENTRYSIZE) for i in range(name_cnt): name_idx = 0xff * ord(name_table[0]) + ord(name_table[1]) name = rffi.charp2str(rffi.ptradd(name_table, 2)) try: int(name) except ValueError: pass else: raise ExitFunctionWithError("Numeric named subpatterns " "are not allowed") subpat_names[name_idx] = name name_table = rffi.ptradd(name_table, name_size) return subpat_names
def get_compiled_regex_cache(interp, regex): pce = interp.space.regex_cache.get(regex) if pce is not None: return pce if '\x00' in regex: raise ExitFunctionWithError("Null byte in regex") # Parse through the leading whitespace, and display a warning if we # get to the end without encountering a delimiter. i = 0 while i < len(regex) and regex[i].isspace(): i += 1 if i == len(regex): raise ExitFunctionWithError("Empty regular expression") # Get the delimiter and display a warning if it is alphanumeric # or a backslash. delimiter = regex[i] if delimiter.isalnum() or delimiter == '\\': raise ExitFunctionWithError("Delimiter must not be alphanumeric " "or backslash") i += 1 pattern_start = i start_delimiter = delimiter if delimiter == '(': delimiter = ')' elif delimiter == '[': delimiter = ']' elif delimiter == '{': delimiter = '}' elif delimiter == '<': delimiter = '>' end_delimiter = delimiter if start_delimiter == end_delimiter: # We need to iterate through the pattern, searching for the # ending delimiter, but skipping the backslashed delimiters. # If the ending delimiter is not found, display a warning. while i < len(regex): if regex[i] == '\\': i += 1 elif regex[i] == end_delimiter: break i += 1 else: raise ExitFunctionWithError("No ending delimiter '%s' found" % delimiter[:]) else: # We iterate through the pattern, searching for the matching # ending delimiter. For each matching starting delimiter, we # increment nesting level, and decrement it for each matching # ending delimiter. If we reach the end of the pattern without # matching, display a warning. brackets = 1 # brackets nesting level while i < len(regex): if regex[i] == '\\': i += 1 elif regex[i] == end_delimiter: brackets -= 1 if brackets == 0: break elif regex[i] == start_delimiter: brackets += 1 i += 1 else: raise ExitFunctionWithError("No ending matching delimiter '%s' " "found" % delimiter[:]) # Move on to the options pattern_end = i i += 1 # Parse through the options, setting appropriate flags. Display # a warning if we encounter an unknown modifier. coptions = 0 poptions = 0 do_study = False while i < len(regex): option = regex[i] i += 1 # Perl compatible options if option == 'i': coptions |= _pcre.PCRE_CASELESS elif option == 'm': coptions |= _pcre.PCRE_MULTILINE elif option == 's': coptions |= _pcre.PCRE_DOTALL elif option == 'x': coptions |= _pcre.PCRE_EXTENDED # PCRE specific options elif option == 'A': coptions |= _pcre.PCRE_ANCHORED elif option == 'D': coptions |= _pcre.PCRE_DOLLAR_ENDONLY elif option == 'S': do_study = True elif option == 'U': coptions |= _pcre.PCRE_UNGREEDY elif option == 'X': coptions |= _pcre.PCRE_EXTRA elif option == 'u': coptions |= _pcre.PCRE_UTF8 if _pcre.PCRE_UCP is not None: coptions |= _pcre.PCRE_UCP # Custom preg options elif option == 'e': poptions |= PREG_REPLACE_EVAL raise ExitFunctionWithError("The deprecated /e modifier is not " "supported by hippy") elif option == ' ': pass elif option == '\n': pass else: raise ExitFunctionWithError("Unknown modifier '%s'" % option[:]) # XXX missing: #if HAVE_SETLOCALE # if (strcmp(locale, "C")) # tables = pcre_maketables(); #endif # Make a copy of the actual pattern. length = pattern_end - pattern_start pattern = lltype.malloc(rffi.CCHARP.TO, length + 1, flavor='raw') copy_string_to_raw(llstr(regex), pattern, pattern_start, length) pattern[length] = '\x00' # Compile pattern and display a warning if compilation failed. p_error = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw', zero=True) p_erroffset = lltype.malloc(rffi.INTP.TO, 1, flavor='raw', zero=True) tables = lltype.nullptr(rffi.CCHARP.TO) re = _pcre.pcre_compile(pattern, coptions, p_error, p_erroffset, tables) error = p_error[0] erroffset = rffi.cast(lltype.Signed, p_erroffset[0]) lltype.free(p_erroffset, flavor='raw') lltype.free(p_error, flavor='raw') lltype.free(pattern, flavor='raw') # All three raw mallocs above are now freed if not re: raise ExitFunctionWithError("Compilation failed: %s at offset %d" % (rffi.charp2str(error), erroffset)) # If study option was specified, study the pattern and # store the result in extra for passing to pcre_exec. extra = lltype.nullptr(_pcre.pcre_extra) if do_study: soptions = 0 #if _pcre.PCRE_STUDY_JIT_COMPILE is not None: # soptions |= _pcre.PCRE_STUDY_JIT_COMPILE p_error = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw', zero=True) extra = _pcre.pcre_study(re, soptions, p_error) error = p_error[0] lltype.free(p_error, flavor='raw') if error: interp.warn("Error while studying pattern") if not extra: extra = _pcre.hippy_pcre_extra_malloc() rffi.setintfield( extra, 'c_flags', rffi.getintfield(extra, 'c_flags') | _pcre.PCRE_EXTRA_MATCH_LIMIT | _pcre.PCRE_EXTRA_MATCH_LIMIT_RECURSION) capturecount = getfullinfo_int(re, extra, _pcre.PCRE_INFO_CAPTURECOUNT) assert capturecount >= 0 subpat_names = make_subpats_table(capturecount, re, extra) pce = PCE( re, extra, poptions, coptions, # XXX also locale and tables capturecount, subpat_names) interp.space.regex_cache.set(regex, pce) return pce
def _get_hash_algo(algo): try: return _hash_algos[algo]() except KeyError: raise ExitFunctionWithError("Unknown hashing algorithm: %s" % algo, return_value=w_False)