'reads values from s and generates the symbolic number that it would equal
the first char is either a number in the given base, or the result is 0
expression indicates whether or not it was successful'

@staticmethod
def _string_to_int(s, state, region, base, signed, read_length=None):

    cutoff = (read_length == None)
    length = (state.libc.max_strtol_len if cutoff else read_length)
    (expression, _) = strtol._char_to_val(region.load(s, 1), state, base)
    cases = []
    num_bits = min((state.arch.bits * 2), 128)
    current_val = state.se.BVV(0, num_bits)
    num_bytes = state.se.BVS('num_bytes', state.arch.bits)
    constraints_num_bytes = []
    conditions = []
    for i in range(length):
        char = region.load((s + i), 1)
        (condition, value) = strtol._char_to_val(char, state, base)
        cases.append(((num_bytes == i), current_val))
        case_constraints = ((conditions + [state.se.Not(condition)]) + [(num_bytes == i)])
        constraints_num_bytes.append(state.se.And(*case_constraints))
        current_val = ((current_val * base) + value.zero_extend((num_bits - 8)))
        conditions.append(condition)
    if (not cutoff):
        cases.append(((num_bytes == length), current_val))
        case_constraints = (conditions + [(num_bytes == length)])
        constraints_num_bytes.append(state.se.And(*case_constraints))
    state.add_constraints(state.se.Or(*constraints_num_bytes))
    result = state.se.ite_cases(cases, 0)
    max_bits = ((state.arch.bits - 1) if signed else state.arch.bits)
    max_val = ((2 ** max_bits) - 1)
    result = state.se.If((result < max_val), state.se.Extract((state.arch.bits - 1), 0, result), state.se.BVV(max_val, state.arch.bits))
    return (expression, result, num_bytes)
