Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  atree.cpp

  Sprache: C
 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include "options.h"
#include "files.h"
#include "fs.h"
#include <set>
#include <iostream>
#include <sstream>

using namespace std;

bool g_debug = getenv("ATREE_DEBUG") != NULL;
vector<string> g_listFiles;
vector<string> g_inputBases;
map<string, string> g_variables;
string g_outputBase;
string g_dependency;
bool g_useHardLinks = false;

const char* USAGE =
"\n"
"Usage: atree OPTIONS\n"
"\n"
"Options:\n"
"  -f FILELIST    Specify one or more files containing the\n"
"                 list of files to copy.\n"
"  -I INPUTDIR    Specify one or more base directories in\n"
"                 which to look for the files\n"
"  -o OUTPUTDIR   Specify the directory to copy all of the\n"
"                 output files to.\n"
"  -l             Use hard links instead of copying the files.\n"
"  -m DEPENDENCY  Output a make-formatted file containing the list.\n"
"                 of files included.  It sets the variable ATREE_FILES.\n"
"  -v VAR=VAL     Replaces ${VAR} by VAL when reading input files.\n"
"  -d             Verbose debug mode.\n"
"\n"
"FILELIST file format:\n"
"  The FILELIST files contain the list of files that will end up\n"
"  in the final OUTPUTDIR.  Atree will look for files in the INPUTDIR\n"
"  directories in the order they are specified.\n"
"\n"
"  In a FILELIST file, comment lines start with a #.  Other lines\n"
"  are of the format:\n"
"\n"
"    [rm|strip] DEST\n"
"    SRC [strip] DEST\n"
"    -SRCPATTERN\n"
"\n"
"  DEST should be path relative to the output directory.\n"
"  'rm DEST' removes the destination file and fails if it's missing.\n"
"  'strip DEST' strips the binary destination file.\n"
"  If SRC is supplied, the file names can be different.\n"
"  SRCPATTERN is a pattern for the filenames.\n"
"\n";

int usage()
{
    fwrite(USAGE, strlen(USAGE), 1, stderr);
    return 1;
}

static bool
add_variable(const char* arg) {
    const char* p = arg;
    while (*p && *p != '=') p++;

    if (*p == 0 || p == arg || p[1] == 0) {
        return false;
    }

    ostringstream var;
    var << "${" << string(arg, p-arg) << "}";
    g_variables[var.str()] = string(p+1);
    return true;
}

static void
debug_printf(const char* format, ...)
{
    if (g_debug) {
        fflush(stderr);
        va_list ap;
        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
        fflush(stdout);
    }
}

// Escape the filename so that it can be added to the makefile properly.
static string
escape_filename(const string& name)
{
    ostringstream new_name;
    for (string::const_iterator iter = name.begin(); iter != name.end(); ++iter)
    {
        switch (*iter)
        {
            case '$':
                new_name << "$$";
                break;
            default:
                new_name << *iter;
                break;
        }
    }
    return new_name.str();
}

int
main(int argc, charconst* argv)
{
    int err;
    bool done = false;
    while (!done) {
        int opt = getopt(argc, argv, "f:I:o:hlm:v:d");
        switch (opt)
        {
            case -1:
                done = true;
                break;
            case 'f':
                g_listFiles.push_back(string(optarg));
                break;
            case 'I':
                g_inputBases.push_back(string(optarg));
                break;
            case 'o':
                if (g_outputBase.length() != 0) {
                    fprintf(stderr, "%s: -o may only be supplied once -- "
                                "-o %s\n", argv[0], optarg);
                    return usage();
                }
                g_outputBase = optarg;
                break;
            case 'l':
                g_useHardLinks = true;
                break;
            case 'm':
                if (g_dependency.length() != 0) {
                    fprintf(stderr, "%s: -m may only be supplied once -- "
                                "-m %s\n", argv[0], optarg);
                    return usage();
                }
                g_dependency = optarg;
                break;
            case 'v':
                if (!add_variable(optarg)) {
                    fprintf(stderr, "%s Invalid expression in '-v %s': "
                            "expected format is '-v VAR=VALUE'.\n",
                            argv[0], optarg);
                    return usage();
                }
                break;
            case 'd':
                g_debug = true;
                break;
            default:
            case '?':
            case 'h':
                return usage();
        }
    }
    if (optind != argc) {
        fprintf(stderr, "%s: invalid argument -- %s\n", argv[0], argv[optind]);
        return usage();
    }

    if (g_listFiles.size() == 0) {
        fprintf(stderr, "%s: At least one -f option must be supplied.\n",
                 argv[0]);
        return usage();
    }

    if (g_inputBases.size() == 0) {
        fprintf(stderr, "%s: At least one -I option must be supplied.\n",
                 argv[0]);
        return usage();
    }

    if (g_outputBase.length() == 0) {
        fprintf(stderr, "%s: -o option must be supplied.\n", argv[0]);
        return usage();
    }


#if 0
    for (vector<string>::iterator it=g_listFiles.begin();
                                it!=g_listFiles.end(); it++) {
        printf("-f \"%s\"\n", it->c_str());
    }
    for (vector<string>::iterator it=g_inputBases.begin();
                                it!=g_inputBases.end(); it++) {
        printf("-I \"%s\"\n", it->c_str());
    }
    printf("-o \"%s\"\n", g_outputBase.c_str());
    if (g_useHardLinks) {
        printf("-l\n");
    }
#endif

    vector<FileRecord> files;
    vector<FileRecord> more;
    vector<string> excludes;
    set<string> directories;
    set<string> deleted;

    // read file lists
    for (vector<string>::iterator it=g_listFiles.begin();
                                 it!=g_listFiles.end(); it++) {
        err = read_list_file(*it, g_variables, &files, &excludes);
        if (err != 0) {
            return err;
        }
    }

    // look for input files
    err = 0;
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        err |= locate(&(*it), g_inputBases);
    }

    // expand the directories that we should copy into a list of files
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        if (it->sourceIsDir) {
            err |= list_dir(*it, excludes, &more);
        }
    }
    for (vector<FileRecord>::iterator it=more.begin();
                                it!=more.end(); it++) {
        files.push_back(*it);
    }

    // get the name and modtime of the output files
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        stat_out(g_outputBase, &(*it));
    }

    if (err != 0) {
        return 1;
    }

    // gather directories
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        if (it->sourceIsDir) {
            directories.insert(it->outPath);
        } else {
            string s = dir_part(it->outPath);
            if (s != ".") {
                directories.insert(s);
            }
        }
    }

    // gather files that should become directores
    // and directories that should become files
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        if (it->outMod != 0 && it->sourceIsDir != it->outIsDir) {
            deleted.insert(it->outPath);
        }
    }

    // delete files
    for (set<string>::iterator it=deleted.begin();
                                it!=deleted.end(); it++) {
        debug_printf("deleting %s\n", it->c_str());
        err = remove_recursively(*it);
        if (err != 0) {
            return err;
        }
    }

    // remove all files or directories as requested from the input atree file.
    // must be done before create new directories.
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        if (!it->sourceIsDir) {
            if (it->fileOp == FILE_OP_REMOVE &&
                    deleted.count(it->outPath) == 0) {
                debug_printf("remove %s\n", it->outPath.c_str());
                err = remove_recursively(it->outPath);
                if (err != 0) {
                    return err;
                }
            }
        }
    }

    // make directories
    for (set<string>::iterator it=directories.begin();
                                it!=directories.end(); it++) {
        debug_printf("mkdir %s\n", it->c_str());
        err = mkdir_recursively(*it);
        if (err != 0) {
            return err;
        }
    }

    // copy (or link) files that are newer or of different size
    for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
        if (!it->sourceIsDir) {
            if (it->fileOp == FILE_OP_REMOVE) {
                continue;
            }

            debug_printf("copy %s(%ld) ==> %s(%ld)",
                it->sourcePath.c_str(), it->sourceMod,
                it->outPath.c_str(), it->outMod);

            if (it->outSize != it->sourceSize || it->outMod < it->sourceMod) {
                err = copy_file(it->sourcePath, it->outPath);
                debug_printf(" done.\n");
                if (err != 0) {
                    return err;
                }
            } else {
                debug_printf(" skipping.\n");
            }

            if (it->fileOp == FILE_OP_STRIP) {
                debug_printf("strip %s\n", it->outPath.c_str());
                err = strip_file(it->outPath);
                if (err != 0) {
                    return err;
                }
            }
        }
    }

    // output the dependency file
    if (g_dependency.length() != 0) {
        FILE *f = fopen(g_dependency.c_str(), "w");
        if (f != NULL) {
            fprintf(f, "ATREE_FILES := $(ATREE_FILES) \\\n");
            for (vector<FileRecord>::iterator it=files.begin();
                                it!=files.end(); it++) {
                if (!it->sourceIsDir) {
                    fprintf(f, "%s \\\n",
                            escape_filename(it->sourcePath).c_str());
                }
            }
            fprintf(f, "\n");
            fclose(f);
        } else {
            fprintf(stderr, "error opening manifest file for write: %s\n",
                    g_dependency.c_str());
        }
    }

    return 0;
}

Messung V0.5 in Prozent
C=88 H=90 G=88

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-06-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik