Diskussion Code-Formatierung für die C und C++ Foren

Lowl3v3l

Mitglied
devCommunity-Experte
Wenn es auf Alpine-Basis ist müsste das im Paket "clang" mit drin sein, wenn Debian-Basis hat es sein eigenes Paket "clang-format". Nein ich habe keine Ahnung, warum man sich da nicht einigt, oder sich wenigstens mal verständigt, ob es "clang-tools-extra" oder "clang-extra-tools" heißt...
 

JR Cologne

Administrator
Teammitglied
Oh shit, wir hätten uns so viel Aufwand ersparen können. :LOL:

Vielen Dank für den heißen Tipp und deine Hilfe bisher insgesamt! :) (y)

Scheint auf Alpine-Basis zu laufen. Jedenfalls funktioniert clang.
 

Lowl3v3l

Mitglied
devCommunity-Experte
Sehr gut! Ich dachte auch nicht, dass apache so viel probleme macht, ich bin sehr froh, dass ich mich damit so wenig befassen muss xD
 

JR Cologne

Administrator
Teammitglied
So, der erste Entwurf der Web-App ist auf GitHub.

Wichtig ist auf jeden Fall noch, dass mithilfe von CORS-Headern verhindert wird, dass andere die Anwendung ausnutzen können und irgendwelchen Müll da hinschicken.

Zudem müssen wir uns eventuell noch ein paar Gedanken über mögliche XSS-Problemchen machen.
Eigentlich würde ich aber davon ausgehen, dass XenForo das ja automatisch bei der Erstellung des Beitrags filtert und HTML-Sonderzeichen umwandelt...
 

Lowl3v3l

Mitglied
devCommunity-Experte
Super, dann bau ich morgen mal ne Datei für clang-format :)
Wie breite Beiträge lässt das Forum zu? Ist eine 80er Breite für die Code-Tags okay oder zuviel?

mfg
 

german

Aktives Mitglied
devCommunity-Experte
Ist eine 80er Breite für die Code-Tags okay oder zuviel?
Erks :sick: Diese 80er Breite kommt von der Idee, Code ausdrucken zu wollen ohne einen Umbruch zu provozieren. So was macht kein Mensch. In Zeiten von 32" Monitoren ist das IMHO Nonsens und kann weggelassen werden. Dann doch lieber ne Zeilennummerierung in die Tags wo man erkennt wenn Code umgebrochen wurde. Um bei Einrückungen nicht zu weit rauszulaufen, beschränke ich mich beim Posten von Code auf 2 Spaces. Das mag vielleicht Sinn ergeben.

Maybe?:
Code:
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
  AfterClass: true
  AfterControlStatement: true
  AfterEnum: true
  AfterFunction: true
  AfterNamespace: true
  AfterObjCDeclaration: true
  AfterStruct: true
  AfterUnion: true
  AfterExternBlock: false
  BeforeCatch: true
  BeforeElse: true
  IndentBraces: false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
ColumnLimit: 0
CommentPragmas: "suppress"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: false
DerivePointerAlignment: false
FixNamespaceComments: false
IncludeBlocks: Regroup
IncludeCategories:
  - Regex: '^".*"'
    Priority: 1
  - Regex: '^<.*>'
    Priority: 2
  - Regex: '.*'
    Priority: 3
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 2
UseTab: Never
 
Zuletzt bearbeitet:

Lowl3v3l

Mitglied
devCommunity-Experte
Daher frag ich, was hier präferiert wird und wieviel das Forum kann ;) Ich weiß nicht was der Standard für Monitore ist, ich weiß nur dass ich mit meinen 3 29''-Monitoren NICHT der Regelfall bin ;) Ich hätte einfach die LLVM-Guidelines genommen und die Codebreite angepasst, die sind ziemlich vernünftig(aber ich bin auch nur ein Fanboy^^)

mfg
 

german

Aktives Mitglied
devCommunity-Experte
Hehe, dann lass uns ausprobieren, was bei deine 3x 29" Monitoren im Vergleich zu meinem 10" Netbook rauskommt, das ich aus Bequemlichkeit üblicherweise auf der Couch auf den Knien habe. Über den Stil lässt sich am Ende sowieso nicht streiten. Jeder entwickelt seinen eigenen. Ist aber OK wenn dann im Forum zumindest Konsistenz herrscht, was auch immer das dann ist :)
 

Lowl3v3l

Mitglied
devCommunity-Experte
Meine Config die ich üblicherweise für Code benutze sieht einfach so aus ^^ :

Code:
---
BasedOnStyle: LLVM
ColumnLimit: '180'
...
 

german

Aktives Mitglied
devCommunity-Experte
Ja, klar, lass uns doch simpel starten. Und wenn es Änderungswünsche gibt, kann man einzelne Parameter immer noch anpassen. Wie gesagt, ich bestehe nicht darauf dass das möglichst nahe an dem Format liegt was ich für mich gewohnt bin. Solang das gut lesbar im Forum ist, ist das absolut okay. Was ich in dem Zusammenhang vielleicht von vorn herein anpassen würde, wäre die Einrückung, um einfach so wenig wie möglich Zeilenumbrüche zu provozieren.
 

Lowl3v3l

Mitglied
devCommunity-Experte
Der LLVM-Style benutzt ne Standard-Einrückungsbreite, wenn er nicht aligned, von zwei, wenn er zwangsweise umbricht von vier. Ich denke das ist okay, unter 2 würde ich da kaum gehen.
 

JR Cologne

Administrator
Teammitglied
Der Standard-LLVM-Style + ggf. ein ColumnLimit von 120-180 wäre aus meiner Sicht in Ordnung. (y)
 

JR Cologne

Administrator
Teammitglied
So, ich melde mich mal wieder zurück, was das Thema Code-Formatierung betrifft.
Ich bin mittlerweile dabei, das XenForo Add-on für die Code-Formatierung zu entwickeln.

Folgendes Problem:
Ich hatte testweise mal verschiedene Codes, die bisher hier im Forum gepostet wurden, durchgespielt.
Grundsätzlich scheint alles zu funktionieren, nur leider macht der folgende Beitragstext von @lano Probleme.

Es geht eigentlich um das hier:
C:
/* juisck */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#define BUF 4096

char *extract(const char *const string, const char *const left, const char *const right) {
    char  *head;
    char  *tail;
    size_t length;
    char  *result;

    if ((string == NULL) || (left == NULL) || (right == NULL))
        return NULL;
    length = strlen(left);
    head   = strstr(string, left);
    if (head == NULL)
        return NULL;
    head += length;
    tail  = strstr(head, right);
    if (tail == NULL)
        return tail;
    length = tail - head;
    result = malloc(1 + length);
    if (result == NULL)
        return NULL;
    result[length] = '\0';

    memcpy(result, head, length);
    return result;
}


int main (int argc, char **argv) {

    int tsocket;
    char *HTTPbuffer = malloc (BUF);
    char *XMLbuffer = malloc (BUF);
    char *MASTERbuffer = malloc (BUF);
    struct sockaddr_in address;
    struct hostent *he;
    int size;

    char *url = "/Jason/UpdateInfoService";
    char *server = "jws.avm.de";

    char *fb_name = "FRITZ!Box 7590";
    char *fb_hw = "226";
    unsigned int fb_major = 154;
    unsigned int fb_minor = 1;
    unsigned int fb_patch = 1;
    unsigned int fb_build = 10000;
    char *fb_type = "1";
    char *fb_serial = "0000000000";
    char *fb_oem = "avm";
    char *fb_lang ="de";
    char *fb_country = "049";
    char *fb_annex = "B";
    char *fb_flags; // ToDo
    unsigned int fb_updateconfig = 3;
    char *fb_provider = "vodafone2_vdsl";
    char *fb_provider_name = "Vodafone";


    snprintf(MASTERbuffer, BUF,
    "<e:BoxInfoMeshMaster xmlns:e=\"http://juis.avm.de/updateinfo\" xmlns:q=\"http://juis.avm.de/request\">"
        "<q:Name>FRITZ!Box 7590</q:Name>"
        "<q:HW>226</q:HW>"
        "<q:Major>154</q:Major>"
        "<q:Minor>7</q:Minor>"
        "<q:Patch>19</q:Patch>"
        "<q:Buildnumber>77204</q:Buildnumber>"
        "<q:Buildtype>1001</q:Buildtype>"
        "<q:Serial>989BCB312396</q:Serial>"
        "<q:OEM>avm</q:OEM>"
        "<q:Lang>de</q:Lang>"
        "<q:Country>049</q:Country>"
        "<q:Annex>B</q:Annex>"
        "<q:Flag>crashreport</q:Flag>"
        "<q:Flag>avm_acs</q:Flag>"
        "<q:Flag>myfritz_letsencrypt</q:Flag>"
        "<q:Flag>medium_dsl</q:Flag>"
        "<q:Flag>mesh_master</q:Flag>"
        "<q:UpdateConfig>3</q:UpdateConfig>"
        "<q:Provider>vodafone2_vdsl</q:Provider>"
        "<q:ProviderName>Vodafone</q:ProviderName>"
    "</e:BoxInfoMeshMaster>");


    snprintf(XMLbuffer, BUF,
    "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap-enc= \"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:e=\"http://juis.avm.de/updateinfo\" xmlns:q=\"http://juis.avm.de/request\">\n"
    "<soap:Header/>\n"
    "<soap:Body>\n"
    "<e:BoxFirmwareUpdateCheck>\n"
        "<e:RequestHeader>\n"
            "<q:Nonce>ixwoteLGzmKa4AefeGbO8w==</q:Nonce>\n"
            "<q:UserAgent>Box</q:UserAgent>\n"
            "<q:ManualRequest>true</q:ManualRequest>\n"
        "</e:RequestHeader>\n"
        "<e:BoxInfo>\n"
            "<q:Name>%s</q:Name>\n"
            "<q:HW>%s</q:HW>\n"
            "<q:Major>%d</q:Major>\n"
            "<q:Minor>%d</q:Minor>\n"
            "<q:Patch>%d</q:Patch>\n"
            "<q:Buildnumber>%d</q:Buildnumber>\n"
            "<q:Buildtype>%s</q:Buildtype>\n"
            "<q:Serial>%s</q:Serial>\n"
            "<q:OEM>%s</q:OEM>\n"
            "<q:Lang>%s</q:Lang>\n"
            "<q:Country>%s</q:Country>\n"
            "<q:Annex>%s</q:Annex>\n"
            "<q:Flag>crashreport</q:Flag>\n"
            "<q:Flag>avm_acs</q:Flag>\n"
            "<q:Flag>myfritz_letsencrypt</q:Flag>\n"
            "<q:Flag>medium_dsl</q:Flag>\n"
            "<q:Flag>mesh_master</q:Flag>\n"
            "<q:UpdateConfig>%d</q:UpdateConfig>\n"
            "<q:Provider>%s</q:Provider>\n"
            "<q:ProviderName>%s</q:ProviderName>\n"
        "</e:BoxInfo>\n"
    "</e:BoxFirmwareUpdateCheck>\n"
    "</soap:Body>\n"
    "</soap:Envelope>",fb_name,fb_hw,fb_major,fb_minor,fb_patch,fb_build,fb_type,fb_serial,fb_oem,fb_lang,fb_country,fb_annex,fb_updateconfig,fb_provider,fb_provider_name);

    snprintf(HTTPbuffer, BUF,
    "POST %s HTTP/1.1\r\n"
    "Host: %s:80\r\n"
    "Content-Length: %d\r\n"
    "Content-Type: text/xml; charset=\"utf-8\"\r\n\r\n%s",url,server,strlen(XMLbuffer),XMLbuffer);


  he = gethostbyname(server);
    if (he == NULL){
    exit(1);
    }



    if ((tsocket=socket(AF_INET, SOCK_STREAM, 0)) > 0) {
//        printf ("Socket wurde angelegt\n");
    }

    address.sin_family = AF_INET;
    address.sin_port = htons (80);
    address.sin_addr = *((struct in_addr *)he->h_addr);

    if (connect(tsocket, (struct sockaddr *) &address, sizeof(address)) == 0) {
//        printf ("Verbindung mit dem Server (%s) hergestellt\n", inet_ntoa(address.sin_addr));
    }



    send(tsocket, HTTPbuffer, strlen(HTTPbuffer), 0);

    size = recv(tsocket, HTTPbuffer, BUF-1, 0);
      if( size > 0) HTTPbuffer[size] = '\0';
//      printf ("Nachricht erhalten:\n%s\n\n", HTTPbuffer);

    char *value;


    value = extract(HTTPbuffer, "<ns3:Found>", "</ns3:Found>");
    if (value != NULL) {
//        printf("%s\n", value);
    }
    int ret = strcmp (value, "true");
    if(ret != 0) {
      printf("Keine Firmware gefunden!\n");
    exit(1);
    }

    free(value);





    value = extract(HTTPbuffer, "<ns3:Name>", "</ns3:Name>");
    if (value != NULL)
        printf("%s\n", value);
    free(value);

    value = extract(HTTPbuffer, "<ns3:Version>", "</ns3:Version>");
    if (value != NULL)
        printf("%s\n", value);
    free(value);

    value = extract(HTTPbuffer, "<ns3:DownloadURL>", "</ns3:DownloadURL>");
    if (value != NULL)
        printf("%s\n", value);
    free(value);

    value = extract(HTTPbuffer, "<ns3:InfoURL>", "</ns3:InfoURL>");
    if (value != NULL)
        printf("%s\n", value);
    free(value);




  close (tsocket);
return EXIT_SUCCESS;
}
Ich will den Server nach neuen Versionen abfragen. Dazu muss man ihm mitteilen welche Hardware man hat. Name und HWID und Major.
Der Name, hwid und major sind immer zusammen und geben die Hardware an.

Loop jetzt deshalb weil ich nach Firmware für alle Boxen suchen will.

Germans Idee ist in sofern nicht schlecht, weil wenn ich dem Programm jetzt nur die Hardware id übergebe, für ne single Anfrage, es sich selber den Namen irgendwie fischen müsste.

Wie ihr seht, enthält dieser Code mit Zeichen wie \0.
Die Folge ist, dass die Funktion preg_replace() durcheinander kommt. 🤭

Seht selbst und führt Folgendes aus:
Code:
php -r "var_dump(preg_replace('/.*/', 'test\0hallo', 'test\0hallo'));"
Das Ergebnis:
Code:
string(29) "testtest\0hallohallotesthallo"
Meine Frage: Hat jemand irgendeine Idee, wie wir dieses Problem umgehen/beheben können?
 

Mat

Mitglied
Hmm, brauchen wir da aufgrund der möglichen Inputs nicht sowieso mb_ereg_replace? Das müsste auch das Escaping übernehmen.
 

JR Cologne

Administrator
Teammitglied
Um den sicheren Umgang mit den Inputs muss ich mich sowieso noch kümmern.
Diesbezüglich könnt ihr also gerne Änderungen vorschlagen bzw. allgemeine Tipps geben.
Das Problem ist ja, dass wir bspw. HTML-Zeichen nicht einfach maskieren können, weil diese sonst im Forum im Code-Block nicht richtig dargestellt werden.

Soweit ich das der PHP-Doku entnehmen kann, scheint im Gegensatz preg_replace automatisch das Escaping zu übernehmen, während mb_ereg_replace dies nicht automatisch macht.

Noch zu meinem Beispiel des Problems mit preg_replace.
Eigentlich sollte ja die Ausgabe test\0hallo erfolgen.
Der Versuch, \0 mit einem Backslash zu escapen, scheitert also.
 
Zuletzt bearbeitet:

german

Aktives Mitglied
devCommunity-Experte
Eigentlich sollte ja die Ausgabe test\0hallo erfolgen.
Warte, das hat aber nichts mit dem \0 zu tun. Wenn du das mal aus dem Teststring rausschmeißt, bekommst du das:
1588414621027.png


Was das Escapen angeht, kann ich bis zu 4 Parse Vorgänge für das Beispiel logisch nachvollziehen:
1) Du rufst PHP aus der Shell auf. Heißt, die Shell parst die Kommandozeile.
2) PHP muss das was als Kommandozeile ankommt parsen und tokenizen
3) Die Stringregeln von PHP könnten zusätzlich zum Tragen kommen.
4) Die Regex Regeln kommen zum Tragen.

Alles in allem macht das zigfache Escapen also Sinn. Keinen Sinn ergibt für mich aber dass eine ungerade Zahl von Backslashes funktioniert (bspw. 5) und dass der Backslash im 3. Argument auch ohne Escaping durchgeht. Wie auch immer, der Aufruf aus der Shell wird in der Realität wegfallen. Somit müsstest du das sowieso noch mal neu bewerten und kannst nicht einfach von dem ausgehen, was mit der Kommandozeile rauskommt.
 

JR Cologne

Administrator
Teammitglied
Oh, ok. Jetzt habe ich mir mit dem Beispiel selbst ein Bein gestellt. :D

Unabhängig davon ist es aber so, dass @lano's Code mit dem entsprechenden Zeichen dieses Problem erzeugt, während andere Codes wie erwartet funktionieren...

Ich werde mal ein anderes Beispiel zusammenstellen.

Edit:
Ich versteh' die Welt nicht mehr. :cautious:

PHP:
<?php

const REGEX = '/(\[CODE(?:=([a-z]+)?)?\])((?:.*\n?)*)/';

// expected: test\0hallo
echo '<pre>', preg_replace('/.*/', 'test\0hallo', 'test\0hallo'), '</pre>';
// expected: testhallo
echo '<pre>', preg_replace('/.*/', 'testhallo', 'testhallo'), '</pre>';

// expected: Hallo, mein Code: [CODE]test
echo '<pre>', preg_replace(REGEX, '[CODE]test', 'Hallo, mein Code: [CODE] test'), '</pre>';
// expected: Hallo, mein Code: [CODE]<?php echo 'hello';
echo '<pre>', preg_replace(REGEX, "[CODE]<?php echo 'hello';", "Hallo, mein Code: [CODE]<?php echo 'hello' ;"), '</pre>';
// expected: Hallo, mein Code: [CODE=c]result[length] = "\0";
echo '<pre>', preg_replace(REGEX, '[CODE=c]result[length] = "\0";', 'Hallo, mein Code: [CODE=c]result[length] = "\0" ;'), '</pre>';
Ausgabe:
Code:
testtest\0hallohallotesthallo

testhallotesthallo

Hallo, mein Code: [CODE]test

Hallo, mein Code: [CODE]

Hallo, mein Code: [CODE=c]result[length] = "[CODE=c]result[length] = "\0" ;";

Btw: Es geht die ganze Zeit im Prinzip um folgende Code-Zeile: https://github.com/dev-community-de/code-formatter/blob/master/app/CodeFormatterApp.php#L181
 
Zuletzt bearbeitet:

german

Aktives Mitglied
devCommunity-Experte
Ich blicke da auch nicht durch. Hab mir PHP vor etlichen Jahren mal kurz angesehen und wieder auf Seite gelegt. addcslashes hilft vielleicht.
Code:
steffen@LAPTOP-4V30SLA6:/mnt/c/Users/steffen$ php -r "var_dump(preg_replace('/.*/', addcslashes('test\0hallo', '\\\\'), 'test\0hallo'));"
string(22) "test\0hallotest\0hallo"
steffen@LAPTOP-4V30SLA6:/mnt/c/Users/steffen$ php -r "var_dump(preg_replace('/.*/', addcslashes('test\0hallo', '\\\'), 'test\0hallo'));"

string(22) "test\0hallotest\0hallo"
steffen@LAPTOP-4V30SLA6:/mnt/c/Users/steffen$ php -r "var_dump(preg_replace('/.*/', addcslashes('test\0hallo', '\134'), 'test\0hallo'));
"
string(22) "test\0hallotest\0hallo"
 
Oben Unten