grammar CleartoolOutput; @header{ package net.sourceforge.clearcase.commandline.parser; import net.sourceforge.clearcase.ClearCase; import net.sourceforge.clearcase.ClearCaseElementState; import net.sourceforge.clearcase.ClearCaseException; } @lexer::header{ package net.sourceforge.clearcase.commandline.parser; } main returns [List elements = new ArrayList()] : (e=line { try { if (e != null) { elements.add(e); } } catch (ClearCaseException cce) { throw new ClearCaseException(cce.getErrorCode(), cce.getElements(), (ClearCaseElementState[])elements.toArray(new ClearCaseElementState[elements.size()])); } } (NEWLINE+|EOF))*; line returns [ClearCaseElementState el] : ( a=error | warning | a=lslong | a=mkdir | a=mkelem | a=checkout | a=checkin | mv | a=uncheckout | a=update ) {el = a;} ; error returns [ClearCaseElementState el] : {int exceptionCode = 0;} {boolean throwException = false;} 'cleartool: Error:' ('Entry' 'named' elem=STRING 'already' 'exists.' {throwException = true; exceptionCode |= ClearCase.ERROR_ALREADY_ADDED;} | 'Element' elem=STRING 'has' 'checkouts.' {throwException = true; exceptionCode |= ClearCase.ERROR_ALREADY_CHECKED_OUT;} | 'Element' elem=STRING 'is' 'already' 'checked' 'out' 'to' 'view' STRING DOT {el = new ClearCaseElementState($elem.text, ClearCase.IS_ELEMENT | ClearCase.ERROR_ALREADY_CHECKED_OUT);} | 'Can\u0027t' 'modify' 'directory' elem=STRING 'because' 'it' 'is' 'not' 'checked' 'out.' {throwException = true; exceptionCode |= ClearCase.ERROR_DIR_IS_NOT_CHECKED_OUT;} | 'Unable' 'to' 'access' elem=STRING ':' 'No' 'such' 'file' 'or' 'directory.' {throwException = true; exceptionCode |= ClearCase.ERROR_NOT_ACCESSIBLE;} | 'By' 'default' 'won\u0027t' 'create' 'version' 'with' 'data' 'identical' 'to' 'predecessor.' {el = new ClearCaseElementState($elem.text, ClearCase.IS_ELEMENT | ClearCase.ERROR_IDENTICAL_TO_PREDECESSOR);} | (LITERAL | STRING | DOT)+) {if (throwException) throw new ClearCaseException(exceptionCode, new String[]{$elem.text}, null);}; warning : 'cleartool: Warning:' (LITERAL | STRING | DOT)+; checkout returns [ClearCaseElementState el] : ('Checked' 'out' element=STRING 'from' 'version' ver=STRING DOT? {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_OUT, $ver.text);} | 'Checking' 'out' 'parent' 'directory' element=STRING DOT {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_OUT);}) ; checkin returns [ClearCaseElementState el] : 'Checked' 'in' element=STRING 'version' ver=STRING DOT {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_IN, $ver.text);} ; mkdir returns [ClearCaseElementState el] : ('Created' 'directory' 'element' element=STRING DOT | 'Created' 'parent' 'directory' 'element' element=STRING DOT | 'Making' 'dir' element=STRING DOT) {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_IN);} ; mkelem returns [ClearCaseElementState el] : ('Created' 'element' element=STRING LPAREN 'type' STRING RPAREN DOT | 'Creating' 'parent' 'directory' 'element' element=STRING DOT) {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_IN);} ; mv : 'Moved' STRING 'to' STRING DOT; lscheckouts : element=STRING 'Predecessor:' predecessor=STRING 'Status:' status=coStatus ; // TODO Test for derived and symbolic link lslong returns [ClearCaseElementState el] : state=typeElement ( LPAREN derivedType RPAREN element=filename '@@' vers=filename | element=filename ('-->' filename | '@@' vers=filename '[not loaded]'?)? // view private or link ('from' LITERAL {state |= ClearCase.CHECKED_OUT;})? NEWLINE? rule ) { if ((state & ClearCase.CHECKED_OUT) != state) { state |= ClearCase.CHECKED_IN; } el = new ClearCaseElementState(element, state, vers); }; rmname returns [ClearCaseElementState el] : 'Removed' element=STRING DOT {el = new ClearCaseElementState($element.text, ClearCase.VIEW_PRIVATE); } ; uncheckout returns [ClearCaseElementState el] : 'Checkout cancelled for' element=STRING DOT {el = new ClearCaseElementState($element.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_IN);} ; update returns [ClearCaseElementState el] : 'Loading' s=STRING LPAREN LITERAL LITERAL RPAREN DOT { el = new ClearCaseElementState($s.text, ClearCase.IS_ELEMENT | ClearCase.CHECKED_IN);} ; coStatus : 'reserved' | 'unreserved'; typeElement returns [int state] : 'view' 'private' ('object' | 'directory') {$state = ClearCase.VIEW_PRIVATE;} | 'derived' 'object' 'version'? {$state = 0;} // TODO : Check the value | 'symbolic' 'link' {$state = ClearCase.LINK | ClearCase.IS_ELEMENT;} | 'directory'? 'version' {$state = ClearCase.IS_ELEMENT;}; derivedType : 'nonshareable' | 'unshared' | 'promoted' | 'shared'; filename returns [String name] : e=LITERAL f=filename?{name=$e.text + " " + f;}; rule: 'Rule:' LITERAL+; LITERAL : CHAR(CHAR|DOT)(CHAR|DOT)*; // newline NEWLINE : ( '\r' '\n' // DOS | '\n' // UNIX | '\r' // MAC ) ; WS : (' ' | '\t')+ {$channel=HIDDEN;}; LPAREN : '('; RPAREN : ')'; STRING : '"'! ( ~'"' ) * '"'! ; DOT : '.'; fragment CHAR : 'A'..'Z' | 'a'..'z' | '\u0080'..'\ufffe' | '0'..'9' | '/' | '\\' | '?' | '*' | '-' | '+' | ':' | '$' | '_' ;