[Tcsh] One-line command parsing
Matheus
tateusg at protonmail.com
Fri Sep 4 09:39:48 EDT 2026
case NODE_LINE:
pid = pfork(t, -1);
if (pid != 0) {
pwait();
break;
}
cleanup_push(&fntmp, fntmp_cleanup);
fnptr = &fntmp;
fnlist(t);
pline(ptr = fntmp.next);
fnexec(&ptr, &fntmp, -1, do_glob);
cleanup_until(&fntmp);
doneinp = 1;
break;
https://github.com/tcsh-org/tcsh/pull/125
Guess I fixed all the bugs for now, though this was tested sparsely. Note I fork the shell. I had interruption issues without a fork.
I guess running commands in background isn't possible from within the control structure.
while 1 ; end ; & echo okay
This shall work. The following shall fail.
while 1 ; echo okay & end ;
> I managed to fix sub-shells for one-line control structures. I found another bug. @ doesn't parse correctly, returning a "missing expression" error. Oddly, from within a sub-shell, the foreach/end variable is set accordingly.
>
> > foreach/end is implemented as of now. There's a little bug, though. For some reason setv() doesn't reset the variable.
> >
> > ( foreach word ( a b c ) ; echo $word ; end ; )
> >
> > doesn't work as expected. Only a is printed.
> >
> > while (top->vec[1] != NULL) {
> > ptr = top->next;
> > setv(top->name, quote(Strsave(*top->vec++)), VAR_READWRITE);
> > fnexec(&ptr, end, wanttty, do_glob);
> > }
> >
> > This is my code. Any help is appreciated.
> >
> > > Never mind. I ended up altering sh.sem.c. I was afraid altering sh.func.c would be dangerous.
> > >
> > > The implementation is almost done, though no deep testing was performed. I have if/endif and while/end working on one-line.
> > >
> > > One drawback to be noted is that sub-shells may not be used within control structures. I intentionally left this as an error.
> > >
> > > I'm trying the best to implement this.
> > >
> > > > The whole parser and lexical analyzer needs to be redone. Patching it is a losing cause.
> > > >
> > > >
> > > > christos
> > > >
> > > > > On Aug 24, 2026, at 12:59 PM, Matheus <tateusg at protonmail.com> wrote:
> > > > >
> > > > > Because I first tried to implement this on top of a temporary function, I altered how semicolons are parsed. Notably, the command-line must end with a semicolon. This is only true when a semicolon is inserted. I.e.: a ; b ;. However, the behavior in sh.sem.c wasn't altered.
> > > > >
> > > > > Though I don't know if this is the best solution to implement one-line command parsing for control structures, this is what I achieved.
> > > > >
> > > > > I've only decided to implement this because of this issue somebody posted on my repository. I, for one, couldn't care less whether one-line command parsing for control structures is a feature or not. I mean one could achieve this behavior using a function.
> > > > >
> > > > > Regarding functions, I came to realize the implementation is somewhat bad. I dislike the use of pipe(). This is messy. I need to reorganize the project.
> > > > >
> > > > >> What is the implication for the existing syntax? I.e. how are existing scripts affected?
> > > > >>
> > > > >> christos
> > > > >>
> > > > >>> On Aug 24, 2026, at 10:51 AM, Matheus <tateusg at protonmail.com> wrote:
> > > > >>>
> > > > >>> https://github.com/Krush206/etcsh/pull/2
> > > > >>> Hello. I'm writing this e-mail as a matter of contribution. I forked Tcsh, and added some features. My most-recent contribution is on one-line command parsing. I'm currently working on an implementation to parse control structures in a single line, as in Bourne shells.
> > > > >>>
> > > > >>> At first, I thought on parsing one-line commands on top of a temporary function. This turned out to be too complicated. Instead, I parse semicolons into a new node mode [NODE_FUNC]. I implemented a new mode [F_LINE]. I "reparse" the entire tree, setting the F_LINE bit to every command node [NODE_COMMAND]. Then, in execute(), I walk through the entire tree, analyzing which of the NODE_COMMAND entries contain the F_LINE mode. The node shall be saved in a circular linked list for each containing the F_LINE mode. Next, the circular linked list is analyzed from search1(). The parsing is almost the same from search().
> > > > >>>
> > > > >>> This is still a work in progress. Not ready for production use. I don't know if this is 100% feasible, though, compared to past implementations, progressed quite fairly.
> > > > >>>
> > > > >>> I'd appreciate for contributions and feedback.
> > > > >>>
> > > > >>> Thank you.
> > > > >>> --
> > > > >>> Tcsh mailing list
> > > > >>> Tcsh at astron.com
> > > > >>> https://mailman.astron.com/mailman/listinfo/tcsh
> > > > >>
> > > > >>
> > > >
> > > >
More information about the Tcsh
mailing list