Skip to content

Commit

Permalink
Fix #88.
Browse files Browse the repository at this point in the history
  • Loading branch information
yurug committed Mar 27, 2019
1 parent 1c0c74a commit ae44c87
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/CST.ml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ and word_component =
| WordAssignmentWord of assignment_word
| WordDoubleQuoted of word
| WordSingleQuoted of word
| WordTildePrefix of string
| WordLiteral of string
| WordVariable of variable
| WordGlobAll (* asterisk *)
Expand Down
1 change: 1 addition & 0 deletions src/prelexerState.ml
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ let return ?(with_newline=false) lexbuf (current : prelexer_state) tokens =
| QuotingMark _ -> []
) (buffer current)))
in
let csts = TildePrefix.recognize csts in
[Pretoken.PreWord (w, csts)]
in
let tokens = if with_newline then tokens @ [Pretoken.NEWLINE] else tokens in
Expand Down
63 changes: 63 additions & 0 deletions src/tildePrefix.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
(**************************************************************************)
(* -*- tuareg -*- *)
(* *)
(* Copyright (C) 2017,2018,2019 Yann Régis-Gianas, Nicolas Jeannerod, *)
(* Ralf Treinen. *)
(* *)
(* This is free software: you can redistribute it and/or modify it *)
(* under the terms of the GNU General Public License, version 3. *)
(* *)
(* Additional terms apply, due to the reproduction of portions of *)
(* the POSIX standard. Please refer to the file COPYING for details. *)
(**************************************************************************)

(*specification
A "tilde-prefix" consists of an unquoted <tilde> character at the
beginning of a word, followed by all of the characters preceding
the first unquoted <slash> in the word, or all the characters in
the word if there is no <slash>. In an assignment (see XBD Variable
Assignment), multiple tilde-prefixes can be used: at the beginning
of the word (that is, following the <equals-sign> of the
assignment), following any unquoted <colon>, or both. A
tilde-prefix in an assignment is terminated by the first unquoted
<colon> or <slash>. If none of the characters in the tilde-prefix
are quoted, the characters in the tilde-prefix following the
<tilde> are treated as a possible login name from the user
database. A portable login name cannot contain characters outside
the set given in the description of the LOGNAME environment
variable in XBD Other Environment Variables. If the login name is
null (that is, the tilde-prefix contains only the tilde), the
tilde-prefix is replaced by the value of the variable HOME. If HOME
is unset, the results are unspecified. Otherwise, the tilde-prefix
shall be replaced by a pathname of the initial working directory
associated with the login name obtained using the getpwnam()
function as defined in the System Interfaces volume of
POSIX.1-2017. If the system does not recognize the login name, the
results are undefined.
*)
open CST

let find_login s =
match Str.(split (regexp "/") s) with
| login :: rem -> [WordTildePrefix login; WordLiteral (String.concat "/" rem)]
| _ -> assert false (* Because there is slash, or not. *)

let rec make_tilde_prefix_explicit rhs_assignment = function
| (WordLiteral s) as cst when s <> "" ->
if s.[0] = '~' then (
if rhs_assignment then
let s = Str.(split (regexp ":") s) in
List.(flatten (map find_login s))
else
find_login s
) else [cst]
| WordAssignmentWord (name, Word (s, csts)) ->
let csts = recognize ~rhs_assignment:true csts in
[WordAssignmentWord (name, Word (s, csts))]
| cst ->
[cst]

and recognize ?(rhs_assignment=false) csts =
List.(flatten (map (make_tilde_prefix_explicit rhs_assignment) csts))
2 changes: 2 additions & 0 deletions tests/good/2.6-word-expansions/2.6.1-tilde-prefix/login.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
echo ~knuth/foo/bar
X=~kn:~/bin:~darkvador/secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[
"Program_LineBreak_CompleteCommands_LineBreak",
[ "LineBreak_Empty" ],
[
"CompleteCommands_CompleteCommands_NewlineList_CompleteCommand",
[
"CompleteCommands_CompleteCommand",
[
"CompleteCommand_CList",
[
"CList_AndOr",
[
"AndOr_Pipeline",
[
"Pipeline_PipeSequence",
[
"PipeSequence_Command",
[
"Command_SimpleCommand",
[
"SimpleCommand_CmdName_CmdSuffix",
[
"CmdName_Word",
[ "Word", "echo", [ [ "WordName", "echo" ] ] ]
],
[
"CmdSuffix_Word",
[
"Word",
"~knuth/foo/bar",
[
[ "WordTildePrefix", "~knuth" ],
[ "WordLiteral", "foo/bar" ]
]
]
]
]
]
]
]
]
]
]
],
[ "NewLineList_NewLine" ],
[
"CompleteCommand_CList",
[
"CList_AndOr",
[
"AndOr_Pipeline",
[
"Pipeline_PipeSequence",
[
"PipeSequence_Command",
[
"Command_SimpleCommand",
[
"SimpleCommand_CmdPrefix",
[
"CmdPrefix_AssignmentWord",
[
[ "Name", "X" ],
[
"Word",
"~kn:~/bin:~darkvador/secret",
[
[ "WordTildePrefix", "~kn" ],
[ "WordLiteral", "" ],
[ "WordTildePrefix", "~" ],
[ "WordLiteral", "bin" ],
[ "WordTildePrefix", "~darkvador" ],
[ "WordLiteral", "secret" ]
]
]
]
]
]
]
]
]
]
]
]
],
[ "LineBreak_Empty" ]
]

0 comments on commit ae44c87

Please sign in to comment.