@@ -1719,7 +1719,6 @@ do_one_cmd(
17191719 cmdmod_T save_cmdmod ;
17201720 int ni ; /* set when Not Implemented */
17211721 char_u * cmd ;
1722- int address_count = 1 ;
17231722
17241723 vim_memset (& ea , 0 , sizeof (ea ));
17251724 ea .line1 = 1 ;
@@ -2045,168 +2044,9 @@ do_one_cmd(
20452044 get_wincmd_addr_type (skipwhite (p ), & ea );
20462045 }
20472046
2048- /* repeat for all ',' or ';' separated addresses */
20492047 ea .cmd = cmd ;
2050- for (;;)
2051- {
2052- ea .line1 = ea .line2 ;
2053- switch (ea .addr_type )
2054- {
2055- case ADDR_LINES :
2056- /* default is current line number */
2057- ea .line2 = curwin -> w_cursor .lnum ;
2058- break ;
2059- case ADDR_WINDOWS :
2060- ea .line2 = CURRENT_WIN_NR ;
2061- break ;
2062- case ADDR_ARGUMENTS :
2063- ea .line2 = curwin -> w_arg_idx + 1 ;
2064- if (ea .line2 > ARGCOUNT )
2065- ea .line2 = ARGCOUNT ;
2066- break ;
2067- case ADDR_LOADED_BUFFERS :
2068- case ADDR_BUFFERS :
2069- ea .line2 = curbuf -> b_fnum ;
2070- break ;
2071- case ADDR_TABS :
2072- ea .line2 = CURRENT_TAB_NR ;
2073- break ;
2074- case ADDR_TABS_RELATIVE :
2075- ea .line2 = 1 ;
2076- break ;
2077- #ifdef FEAT_QUICKFIX
2078- case ADDR_QUICKFIX :
2079- ea .line2 = qf_get_cur_valid_idx (& ea );
2080- break ;
2081- #endif
2082- }
2083- ea .cmd = skipwhite (ea .cmd );
2084- lnum = get_address (& ea , & ea .cmd , ea .addr_type , ea .skip ,
2085- ea .addr_count == 0 , address_count ++ );
2086- if (ea .cmd == NULL ) /* error detected */
2087- goto doend ;
2088- if (lnum == MAXLNUM )
2089- {
2090- if (* ea .cmd == '%' ) /* '%' - all lines */
2091- {
2092- ++ ea .cmd ;
2093- switch (ea .addr_type )
2094- {
2095- case ADDR_LINES :
2096- ea .line1 = 1 ;
2097- ea .line2 = curbuf -> b_ml .ml_line_count ;
2098- break ;
2099- case ADDR_LOADED_BUFFERS :
2100- {
2101- buf_T * buf = firstbuf ;
2102-
2103- while (buf -> b_next != NULL
2104- && buf -> b_ml .ml_mfp == NULL )
2105- buf = buf -> b_next ;
2106- ea .line1 = buf -> b_fnum ;
2107- buf = lastbuf ;
2108- while (buf -> b_prev != NULL
2109- && buf -> b_ml .ml_mfp == NULL )
2110- buf = buf -> b_prev ;
2111- ea .line2 = buf -> b_fnum ;
2112- break ;
2113- }
2114- case ADDR_BUFFERS :
2115- ea .line1 = firstbuf -> b_fnum ;
2116- ea .line2 = lastbuf -> b_fnum ;
2117- break ;
2118- case ADDR_WINDOWS :
2119- case ADDR_TABS :
2120- if (IS_USER_CMDIDX (ea .cmdidx ))
2121- {
2122- ea .line1 = 1 ;
2123- ea .line2 = ea .addr_type == ADDR_WINDOWS
2124- ? LAST_WIN_NR : LAST_TAB_NR ;
2125- }
2126- else
2127- {
2128- /* there is no Vim command which uses '%' and
2129- * ADDR_WINDOWS or ADDR_TABS */
2130- errormsg = (char_u * )_ (e_invrange );
2131- goto doend ;
2132- }
2133- break ;
2134- case ADDR_TABS_RELATIVE :
2135- errormsg = (char_u * )_ (e_invrange );
2136- goto doend ;
2137- break ;
2138- case ADDR_ARGUMENTS :
2139- if (ARGCOUNT == 0 )
2140- ea .line1 = ea .line2 = 0 ;
2141- else
2142- {
2143- ea .line1 = 1 ;
2144- ea .line2 = ARGCOUNT ;
2145- }
2146- break ;
2147- #ifdef FEAT_QUICKFIX
2148- case ADDR_QUICKFIX :
2149- ea .line1 = 1 ;
2150- ea .line2 = qf_get_size (& ea );
2151- if (ea .line2 == 0 )
2152- ea .line2 = 1 ;
2153- break ;
2154- #endif
2155- }
2156- ++ ea .addr_count ;
2157- }
2158- /* '*' - visual area */
2159- else if (* ea .cmd == '*' && vim_strchr (p_cpo , CPO_STAR ) == NULL )
2160- {
2161- pos_T * fp ;
2162-
2163- if (ea .addr_type != ADDR_LINES )
2164- {
2165- errormsg = (char_u * )_ (e_invrange );
2166- goto doend ;
2167- }
2168-
2169- ++ ea .cmd ;
2170- if (!ea .skip )
2171- {
2172- fp = getmark ('<' , FALSE);
2173- if (check_mark (fp ) == FAIL )
2174- goto doend ;
2175- ea .line1 = fp -> lnum ;
2176- fp = getmark ('>' , FALSE);
2177- if (check_mark (fp ) == FAIL )
2178- goto doend ;
2179- ea .line2 = fp -> lnum ;
2180- ++ ea .addr_count ;
2181- }
2182- }
2183- }
2184- else
2185- ea .line2 = lnum ;
2186- ea .addr_count ++ ;
2187-
2188- if (* ea .cmd == ';' )
2189- {
2190- if (!ea .skip )
2191- {
2192- curwin -> w_cursor .lnum = ea .line2 ;
2193- /* don't leave the cursor on an illegal line or column */
2194- check_cursor ();
2195- }
2196- }
2197- else if (* ea .cmd != ',' )
2198- break ;
2199- ++ ea .cmd ;
2200- }
2201-
2202- /* One address given: set start and end lines */
2203- if (ea .addr_count == 1 )
2204- {
2205- ea .line1 = ea .line2 ;
2206- /* ... but only implicit: really no address given */
2207- if (lnum == MAXLNUM )
2208- ea .addr_count = 0 ;
2209- }
2048+ if (parse_cmd_address (& ea , & errormsg ) == FAIL )
2049+ goto doend ;
22102050
22112051/*
22122052 * 5. Parse the command.
@@ -2988,6 +2828,179 @@ do_one_cmd(
29882828 #pragma optimize( "", on )
29892829#endif
29902830
2831+ /*
2832+ * Parse the address range, if any, in "eap".
2833+ * Return FAIL and set "errormsg" or return OK.
2834+ */
2835+ int
2836+ parse_cmd_address (exarg_T * eap , char_u * * errormsg )
2837+ {
2838+ int address_count = 1 ;
2839+ linenr_T lnum ;
2840+
2841+ // Repeat for all ',' or ';' separated addresses.
2842+ for (;;)
2843+ {
2844+ eap -> line1 = eap -> line2 ;
2845+ switch (eap -> addr_type )
2846+ {
2847+ case ADDR_LINES :
2848+ // default is current line number
2849+ eap -> line2 = curwin -> w_cursor .lnum ;
2850+ break ;
2851+ case ADDR_WINDOWS :
2852+ eap -> line2 = CURRENT_WIN_NR ;
2853+ break ;
2854+ case ADDR_ARGUMENTS :
2855+ eap -> line2 = curwin -> w_arg_idx + 1 ;
2856+ if (eap -> line2 > ARGCOUNT )
2857+ eap -> line2 = ARGCOUNT ;
2858+ break ;
2859+ case ADDR_LOADED_BUFFERS :
2860+ case ADDR_BUFFERS :
2861+ eap -> line2 = curbuf -> b_fnum ;
2862+ break ;
2863+ case ADDR_TABS :
2864+ eap -> line2 = CURRENT_TAB_NR ;
2865+ break ;
2866+ case ADDR_TABS_RELATIVE :
2867+ eap -> line2 = 1 ;
2868+ break ;
2869+ #ifdef FEAT_QUICKFIX
2870+ case ADDR_QUICKFIX :
2871+ eap -> line2 = qf_get_cur_valid_idx (eap );
2872+ break ;
2873+ #endif
2874+ }
2875+ eap -> cmd = skipwhite (eap -> cmd );
2876+ lnum = get_address (eap , & eap -> cmd , eap -> addr_type , eap -> skip ,
2877+ eap -> addr_count == 0 , address_count ++ );
2878+ if (eap -> cmd == NULL ) // error detected
2879+ return FAIL ;
2880+ if (lnum == MAXLNUM )
2881+ {
2882+ if (* eap -> cmd == '%' ) // '%' - all lines
2883+ {
2884+ ++ eap -> cmd ;
2885+ switch (eap -> addr_type )
2886+ {
2887+ case ADDR_LINES :
2888+ eap -> line1 = 1 ;
2889+ eap -> line2 = curbuf -> b_ml .ml_line_count ;
2890+ break ;
2891+ case ADDR_LOADED_BUFFERS :
2892+ {
2893+ buf_T * buf = firstbuf ;
2894+
2895+ while (buf -> b_next != NULL
2896+ && buf -> b_ml .ml_mfp == NULL )
2897+ buf = buf -> b_next ;
2898+ eap -> line1 = buf -> b_fnum ;
2899+ buf = lastbuf ;
2900+ while (buf -> b_prev != NULL
2901+ && buf -> b_ml .ml_mfp == NULL )
2902+ buf = buf -> b_prev ;
2903+ eap -> line2 = buf -> b_fnum ;
2904+ break ;
2905+ }
2906+ case ADDR_BUFFERS :
2907+ eap -> line1 = firstbuf -> b_fnum ;
2908+ eap -> line2 = lastbuf -> b_fnum ;
2909+ break ;
2910+ case ADDR_WINDOWS :
2911+ case ADDR_TABS :
2912+ if (IS_USER_CMDIDX (eap -> cmdidx ))
2913+ {
2914+ eap -> line1 = 1 ;
2915+ eap -> line2 = eap -> addr_type == ADDR_WINDOWS
2916+ ? LAST_WIN_NR : LAST_TAB_NR ;
2917+ }
2918+ else
2919+ {
2920+ // there is no Vim command which uses '%' and
2921+ // ADDR_WINDOWS or ADDR_TABS
2922+ * errormsg = (char_u * )_ (e_invrange );
2923+ return FAIL ;
2924+ }
2925+ break ;
2926+ case ADDR_TABS_RELATIVE :
2927+ * errormsg = (char_u * )_ (e_invrange );
2928+ return FAIL ;
2929+ case ADDR_ARGUMENTS :
2930+ if (ARGCOUNT == 0 )
2931+ eap -> line1 = eap -> line2 = 0 ;
2932+ else
2933+ {
2934+ eap -> line1 = 1 ;
2935+ eap -> line2 = ARGCOUNT ;
2936+ }
2937+ break ;
2938+ #ifdef FEAT_QUICKFIX
2939+ case ADDR_QUICKFIX :
2940+ eap -> line1 = 1 ;
2941+ eap -> line2 = qf_get_size (eap );
2942+ if (eap -> line2 == 0 )
2943+ eap -> line2 = 1 ;
2944+ break ;
2945+ #endif
2946+ }
2947+ ++ eap -> addr_count ;
2948+ }
2949+ else if (* eap -> cmd == '*' && vim_strchr (p_cpo , CPO_STAR ) == NULL )
2950+ {
2951+ pos_T * fp ;
2952+
2953+ // '*' - visual area
2954+ if (eap -> addr_type != ADDR_LINES )
2955+ {
2956+ * errormsg = (char_u * )_ (e_invrange );
2957+ return FAIL ;
2958+ }
2959+
2960+ ++ eap -> cmd ;
2961+ if (!eap -> skip )
2962+ {
2963+ fp = getmark ('<' , FALSE);
2964+ if (check_mark (fp ) == FAIL )
2965+ return FAIL ;
2966+ eap -> line1 = fp -> lnum ;
2967+ fp = getmark ('>' , FALSE);
2968+ if (check_mark (fp ) == FAIL )
2969+ return FAIL ;
2970+ eap -> line2 = fp -> lnum ;
2971+ ++ eap -> addr_count ;
2972+ }
2973+ }
2974+ }
2975+ else
2976+ eap -> line2 = lnum ;
2977+ eap -> addr_count ++ ;
2978+
2979+ if (* eap -> cmd == ';' )
2980+ {
2981+ if (!eap -> skip )
2982+ {
2983+ curwin -> w_cursor .lnum = eap -> line2 ;
2984+ // don't leave the cursor on an illegal line or column
2985+ check_cursor ();
2986+ }
2987+ }
2988+ else if (* eap -> cmd != ',' )
2989+ break ;
2990+ ++ eap -> cmd ;
2991+ }
2992+
2993+ // One address given: set start and end lines.
2994+ if (eap -> addr_count == 1 )
2995+ {
2996+ eap -> line1 = eap -> line2 ;
2997+ // ... but only implicit: really no address given
2998+ if (lnum == MAXLNUM )
2999+ eap -> addr_count = 0 ;
3000+ }
3001+ return OK ;
3002+ }
3003+
29913004/*
29923005 * Check for an Ex command with optional tail.
29933006 * If there is a match advance "pp" to the argument and return TRUE.
@@ -4292,7 +4305,7 @@ set_one_cmd_context(
42924305}
42934306
42944307/*
4295- * skip a range specifier of the form: addr [,addr] [;addr] ..
4308+ * Skip a range specifier of the form: addr [,addr] [;addr] ..
42964309 *
42974310 * Backslashed delimiters after / or ? will be skipped, and commands will
42984311 * not be expanded between /'s and ?'s or after "'".
0 commit comments