Changeset 435 for topdoc


Ignore:
Timestamp:
Apr 1, 2011 1:52:41 PM (14 years ago)
Author:
jemian
Message:

refactored macro substitution - expect to obey ALL EPICS rules now from AppDevGuide? Chap. 6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified topdoc/src/TopDoc/utilities.py

    r434 r435  
    2020
    2121
    22 COMMENT_PATTERN = re.compile(
    23         r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
     22C_LANGUAGE_COMMENT_RE = r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"'
     23C_LANGUAGE_COMMENT_PATTERN = re.compile(
     24        C_LANGUAGE_COMMENT_RE,
    2425        re.DOTALL | re.MULTILINE
    2526    )
     27
     28# a-z A-Z 0-9 _ -- : . [ ] < > ;
     29EPICS_UNQUOTED_STRING_RE = r'[\d\w_:;.<>\-\[\]]+'
     30EPICS_MACRO_SPECIFICATION_P_RE = "\$\("+EPICS_UNQUOTED_STRING_RE+"\)"
     31EPICS_MACRO_SPECIFICATION_B_RE = "\$\{"+EPICS_UNQUOTED_STRING_RE+"\}"
     32# EPICS_MACRO_DEFAULT_RE cannot find $(P=$(S)), that's OK.
     33# If the inner $(S) was expanded, it would be found then, else macro expansion fails anyway
     34EPICS_MACRO_DEFAULT_RE = EPICS_UNQUOTED_STRING_RE+'='+EPICS_UNQUOTED_STRING_RE
     35EPICS_MACRO_SPECIFICATION_PD_RE = "\$\("+EPICS_MACRO_DEFAULT_RE+"\)"
     36EPICS_MACRO_SPECIFICATION_BD_RE = "\$\{"+EPICS_MACRO_DEFAULT_RE+"\}"
     37
     38EPICS_UNQUOTED_STRING_PATTERN = re.compile(EPICS_UNQUOTED_STRING_RE, 0)
     39EPICS_MACRO_SPECIFICATION_P_PATTERN = re.compile(EPICS_MACRO_SPECIFICATION_P_RE, 0)
     40EPICS_MACRO_SPECIFICATION_B_PATTERN = re.compile(EPICS_MACRO_SPECIFICATION_B_RE, 0)
     41EPICS_MACRO_DEFAULT_PATTERN = re.compile(EPICS_MACRO_DEFAULT_RE, 0)
     42EPICS_MACRO_SPECIFICATION_PD_PATTERN = re.compile(EPICS_MACRO_SPECIFICATION_PD_RE, 0)
     43EPICS_MACRO_SPECIFICATION_BD_PATTERN = re.compile(EPICS_MACRO_SPECIFICATION_BD_RE, 0)
    2644
    2745
     
    3957        else:
    4058            return s
    41     return re.sub(COMMENT_PATTERN, replacer, text)
     59    return re.sub(C_LANGUAGE_COMMENT_PATTERN, replacer, text)
    4260
    4361
     
    8199    @return: string with substitutions applied
    82100    '''
    83     target = source
    84     # diagnostic lines only
    85     # logMessage("replaceMacros(): source = " + source)
    86     # logMessage("replaceMacros(): macros = " + str(macros))
    87     # TODO: It's more complicated than this.  See comment in TopDoc.py
    88     for k, v in macros.items():
    89         if target.find("$(") < 0:
    90             break
    91         key = "$(%s)" % k
    92         tmp = target.replace(key, v)
    93         target = tmp
    94     return target
     101    while True:
     102        replacement_found = False
     103        # substitute the simple macro replacements
     104        for patt in (EPICS_MACRO_SPECIFICATION_P_PATTERN, EPICS_MACRO_SPECIFICATION_B_PATTERN):
     105            for subst_marker in re.findall(patt, source, 0):
     106                parts = re.findall(EPICS_UNQUOTED_STRING_PATTERN, subst_marker, 0)
     107                if len(parts) != 1:
     108                    # add more diagnostics if this happens
     109                    raise Exception, "should only match 1 substitution expression here"
     110                if parts[0] in macros:
     111                    replacement_text = macros[parts[0]]
     112                    replacement_found = True
     113                    source = source.replace(subst_marker, replacement_text)
     114        # substitute the macros with default expressions
     115        for patt in (EPICS_MACRO_SPECIFICATION_PD_PATTERN, EPICS_MACRO_SPECIFICATION_BD_PATTERN):
     116            for subst_marker in re.findall(patt, source, 0):
     117                parts = re.findall(EPICS_UNQUOTED_STRING_PATTERN, subst_marker, 0)
     118                if len(parts) != 2:
     119                    # add more diagnostics if this happens
     120                    raise Exception, "should only match 2 parts here"
     121                macro_variable, default_substitution = parts
     122                if macro_variable in macros:
     123                    replacement_text = macros[macro_variable]
     124                else:
     125                    replacement_text = default_substitution
     126                replacement_found = True
     127                source = source.replace(subst_marker, replacement_text)
     128        if not replacement_found:
     129            break       # nothing more can be done
     130    return source
    95131
    96132
     
    168204if __name__ == '__main__':
    169205    print "need some test and demo function calls"
     206    macro_test_set = ("$(P=$(S))${S_$(P)}string  $(PJ=$(P))${S_$(P)}string  ${_P:9--8}  $(<_.>=bob:) $(P=blue) $(P=red)",
     207                      "$(P=$(S))${S_$(P)}string",
     208                      "$(PJ=$(P))${S_$(P)}string",
     209                      "${_P:9--8}",
     210                      "$(<_.>=bob:)",
     211                      "$(P=blue)",
     212                      "$(P=red)"
     213                      )
     214    macros = {'P': 'pete:', 'S_pete:': 'shoe_'}
     215    for test in macro_test_set:
     216        print replaceMacros(test, macros)
Note: See TracChangeset for help on using the changeset viewer.