1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.build.config;
18 
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
21 
22 /**
23  * Position in a source file.
24  */
25 public class Position implements Comparable<Position> {
26     /**
27      * Sentinel line number for when there is no known line number.
28      */
29     public static final int NO_LINE = -1;
30 
31     private static final Pattern REGEX = Pattern.compile("([^:]*)(?::(\\d)*)?:?\\s*");
32     public static final String UNKNOWN = "<unknown>";
33 
34     private final String mFile;
35     private final int mLine;
36 
Position()37     public Position() {
38         mFile = null;
39         mLine = NO_LINE;
40     }
41 
Position(String file)42     public Position(String file) {
43         mFile = file;
44         mLine = NO_LINE;
45     }
46 
Position(String file, int line)47     public Position(String file, int line) {
48         if (line < NO_LINE) {
49             throw new IllegalArgumentException("Negative line number. file=" + file
50                     + " line=" + line);
51         }
52         mFile = file;
53         mLine = line;
54     }
55 
compareTo(Position that)56     public int compareTo(Position that) {
57         int result = mFile.compareTo(that.mFile);
58         if (result != 0) {
59             return result;
60         }
61         return mLine - that.mLine;
62     }
63 
getFile()64     public String getFile() {
65         return mFile;
66     }
67 
getLine()68     public int getLine() {
69         return mLine;
70     }
71 
72     /**
73      * Return a Position object from a string containing <filename>:<line>, or the default
74      * Position(null, NO_LINE) if the string can't be parsed.
75      */
parse(String str)76     public static Position parse(String str) {
77         final Matcher m = REGEX.matcher(str);
78         if (!m.matches()) {
79             return new Position();
80         }
81         String filename = m.group(1);
82         if (filename.length() == 0 || UNKNOWN.equals(filename)) {
83             filename = null;
84         }
85         String lineString = m.group(2);
86         int line;
87         if (lineString == null || lineString.length() == 0) {
88             line = NO_LINE;
89         } else {
90             try {
91                 line = Integer.parseInt(lineString);
92             } catch (NumberFormatException ex) {
93                 line = NO_LINE;
94             }
95         }
96         return new Position(filename, line);
97     }
98 
99     @Override
toString()100     public String toString() {
101       if (mFile == null && mLine == NO_LINE) {
102         return "";
103       } else if (mFile == null && mLine != NO_LINE) {
104         return UNKNOWN + ":" + mLine + ": ";
105       } else if (mFile != null && mLine == NO_LINE) {
106         return mFile + ": ";
107       } else { // if (mFile != null && mLine != NO_LINE)
108         return mFile + ':' + mLine + ": ";
109       }
110     }
111 }
112