Я хотел бы написать программу на C, которая берет строку в make-файле и обрабатывает ее несколькими способами:
- Если строка содержит двоеточие, мы предполагаем, что онаявляется целевой строкой, и перед двоеточием существует целевое имя.
- В целевых строках мы сохраняем цель в переменной targetName в виде строки с нулевым символом в конце.
- В целевых строках мы затем ищем любые зависимости в той же строке, что и целевые, после двоеточия.Ноль или более пробельных символов (пробелы и табуляции) могут появляться после двоеточия, между зависимостями или в конце строки, но нас интересуют только строки, которые либо: a.Определить существующие файлы на диске, б.Определите другие цели, или c.Определите веб-URL.
Строка, обрабатываемая из make-файла, может выглядеть примерно так:
calcmarks.o : calcmarks.c calcmarks.h globals.o
Где calcmarks.o
- имя цели,и calcmarks.c
, calcmarks.h
и globals.o
- все имена зависимостей, причем первые 2 - это файлы на диске, а окончательная зависимость - еще одна цель.Мы будем хранить calcmarks.o
в переменной targetName , а затем выбирать подходящую структуру данных для хранения других зависимостей.Я хотел бы хранить имена зависимостей таким образом, чтобы мне было легче позже проверить дату изменения любой зависимости и сравнить ее с датой изменения цели, чтобы увидеть, была ли зависимость изменена позднее, чемцель.
Вот код, который я смог придумать до сих пор.По сути, эта функция принимает указатель файла и цель для перестройки и в конечном итоге перестраивает ее.
// filePtr is the text file pointer after going through processVariables
// Target is the name of the target isolated from the command line interface (requested by user)
void processTarget (FILE* filePtr , char target[]) {
// Holds line by line
char buffer[1000];
// Holds name of target with no whitespace
char targetName[1000];
// Boolean to check if the target was indeed found
bool targetFound = false;
while (fgets(buffer , sizeof(buffer) , filePtr) != NULL) {
int i;
for (i = 0; buffer[i] != '\0'; i++) {
// Copying a potential target name until we find a colon
if (buffer[i] == ':') {
// Don't copy the colon, so terminate the string
targetName[i] = '\0';
targetFound = true;
break;
}
targetName[i] = buffer[i];
}
// If the previous loop encountered a target name via the existance of a semicolon
if (targetFound) {
// If the target name is the same as the required target
if (target == targetName) {
// Test for 0 dependencies
if (buffer[i + 1] == '\0') continue; // End of string
int j;
for (j = i + 1; j != '\0'; j++) {
// Processing the line after the colon
}
}
}
}
}
Также обратите внимание, что число зависимостей является переменным;таким образом, если бы я инициализировал конструкцию для хранения их имен, я бы не знал параметр size.
Как искать зависимости после двоеточия, игнорируя пробелы и сохраняя имена зависимостейв структуре данных?
РЕДАКТИРОВАТЬ: Уточнение благодаря @JonathanLeffler: Зависимости, которые должен распознать этот проект, не будут намного сложнее, чем те, которые показаны вниже приведена строка, за исключением веб-адресов.