Macro for integrals, a problem with limits

The problem is, that your \temp in the tried fix is read as one token and not parsed correctly. Inserting a few \expandafters fixes this:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xstring}

\NewDocumentCommand{\Int}{ >{\SplitList{;}}o}{%
    \IfValueT{#1}{\ProcessList{#1}{\IntLimitONE}}\,%
}
\NewDocumentCommand{\IntLimitONE}{m}{%
    \IfSubStr{#1}{*}{\StrSubstitute{#1}{*}{}[\temp]\oint\expandafter\IntSplitLimits\expandafter{\temp}}{\int\IntSplitLimits{#1}}
}
\NewDocumentCommand{\IntSplitLimits}{ >{\SplitArgument{1}{,}}m}{%
    \IfValueT{#1}{\IntLimits#1}%
}
\NewDocumentCommand{\IntLimits}{mm}{%
    _{#1}^{\IfNoValueTF{#2}{}{#2\!\!}}%
}

\begin{document}
  \begin{equation}
     \Int[a,b;*c,d;e,f] f(x,y,z) dxdydz \quad , \quad \Int[*a,b] f(x) dx
  \end{equation}
\end{document}

enter image description here


The outer part is good.

For deciding whether * appears, I use \SplitArgument for at most one occurrence of *; this will produce two arguments, the second of which is -NoValue- in case no asterisk appears.

The rest is just splitting at the comma.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\NewDocumentCommand{\Int}{>{\SplitList{;}}O{}}{%
  \ProcessList{#1}{\IntA}%
}
\NewDocumentCommand{\IntA}{>{\SplitArgument{1}{*}}{m}}{%
  \IntB#1%
}
\NewDocumentCommand{\IntB}{mm}{%
  \IfNoValueTF{#2}
   {\IntC{\int}{#1}}% no *
   {\IntC{\oint}{#2}}% *
}
\NewDocumentCommand{\IntC}{m >{\SplitArgument{1}{,}}m}{%
  \IntD{#1}#2%
}
\NewDocumentCommand{\IntD}{mmm}{%
  #1_{#2}^{#3}%
}

\begin{document}

\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}

\end{document}

enter image description here

With expl3 functions, you can split the argument at ; and map on the sequence so obtained. If the item starts with *, discard it and choose \oint, otherwise choose \int.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\Int}{O{}}
 {
  \simon_int:n { #1 }
 }

\seq_new:N \l_simon_int_args_seq

\cs_new_protected:Nn \simon_int:n
 {
  \seq_set_split:Nnn \l_simon_int_args_seq { ; } { #1 }
  \seq_map_inline:Nn \l_simon_int_args_seq
   {
    \str_if_eq_x:nnTF { \tl_head:n { ##1 } } { * }
     {% * case
      \simon_int_inner:Nf \oint { \tl_tail:n { ##1 } }
     }
     {% no * case
      \simon_int_inner:Nn \int { ##1 }
     }
   }
 }
\cs_new_protected:Nn \simon_int_inner:Nn
 {
  #1 \sb{ \clist_item:nn { #2 } { 1 } }
     \sp{ \clist_item:nn { #2 } { 2 } }
 }
\cs_generate_variant:Nn \simon_int_inner:Nn { Nf }
\ExplSyntaxOff

\begin{document}

\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}

\end{document}

A variant that checks for the asterisk even if not leading the item:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\Int}{O{}}
 {
  \simon_int:n { #1 }
 }

\seq_new:N \l__simon_int_args_seq
\tl_new:N \l__simon_int_ast_tl

\cs_new_protected:Nn \simon_int:n
 {
  \seq_set_split:Nnn \l__simon_int_args_seq { ; } { #1 }
  \seq_map_inline:Nn \l__simon_int_args_seq
   {
    \tl_if_in:nnTF { ##1 } { * }
     {% * case
      \tl_set:Nn \l__simon_int_ast_tl { ##1 }
      \tl_remove_once:Nn \l__simon_int_ast_tl { * }
      \simon_int_inner:NV \oint \l__simon_int_ast_tl
     }
     {% no * case
      \simon_int_inner:Nn \int { ##1 }
     }
   }
 }
\cs_new_protected:Nn \simon_int_inner:Nn
 {
  #1 \sb{ \clist_item:nn { #2 } { 1 } }
     \sp{ \clist_item:nn { #2 } { 2 } }
 }
\cs_generate_variant:Nn \simon_int_inner:Nn { NV }
\ExplSyntaxOff

\begin{document}

\begin{equation}
\Int[a,b;*c,d;e*,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}

\end{document}

enter image description here