list(3) — Linux manual page
用Visual Studio 2022创建CMake项目
* CmakeLists.txt
# CMakeList.txt : Top-level CMake project file, do global configuration
# and include sub-projects here.
#
cmake_minimum_required (VERSION 3.12)
project ("llist")
# Include sub-projects.
add_subdirectory ("llist")
* llist/CMakeLists.txt
# CMakeList.txt : CMake project for llist, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.12)
# Add source to this project's executable.
add_executable (llist "llist.c" "llist.h")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET llist PROPERTY CXX_STANDARD 11)
endif()
# TODO: Add tests and install targets if needed.
* llist/llist.h
// llist.h : Include file for standard system include files,
// or project specific include files.
#pragma once
#ifndef NULL
#define NULL (void *)0
#endif
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
// TODO: Reference additional headers your program requires here.
llist/llist.c
/* llist.c : Defines the entry point for the application.* /
/* #include <sys/queue.h> */
#include <stdio.h>
#include <stdlib.h> /* malloc, free */
#include <string.h> /* strcpy */
#include "llist.h"
struct entry {
char s[256];
LIST_ENTRY(entry) entries;
};
LIST_HEAD(listhead, entry);
int main()
{
struct listhead head;
struct entry* n1, * n2, * np;
/* Initialize the list */
LIST_INIT(&head);
/* Insert at the head */
n1 = malloc(sizeof(struct entry));
strcpy_s(n1->s, 256, "line#1");
LIST_INSERT_HEAD(&head, n1, entries);
/* Insert after */
n2 = malloc(sizeof(struct entry));
strcpy_s(n2->s, 256, "line#2");
LIST_INSERT_AFTER(n1, n2, entries);
struct entry* n3;
n3 = malloc(sizeof(struct entry));
strcpy_s(n3->s, 256, "line#3");
LIST_INSERT_BEFORE(n2, n3, entries);
LIST_FOREACH(np, &head, entries) {
printf("%s\n", np->s);
}
LIST_REMOVE(n2, entries);
free(n2);
LIST_FOREACH(np, &head, entries) {
printf("%s\n", np->s);
}
/* Destroy */
while (LIST_FIRST(&head) != NULL) {
LIST_REMOVE(LIST_FIRST(&head), entries);
free(LIST_FIRST(&head));
}
return 0;
}
选择最外层的CMakeLists.txt 右键Build
CMakePresets.json
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "x86-debug",
"displayName": "x86 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x86-release",
"displayName": "x86 Release",
"inherits": "x86-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
},
{
"name": "macos-debug",
"displayName": "macOS Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
}
]
}